Browse Source

Merge pull request #2263 from odin-lang/compiler-improvements-2022-12

Compiler Improvements for 2022-12
gingerBill 2 years ago
parent
commit
28fb35f2f7
53 changed files with 2627 additions and 4000 deletions
  1. 1 0
      build.bat
  2. 76 76
      src/array.cpp
  3. 79 79
      src/big_int.cpp
  4. 6 6
      src/bug_report.cpp
  5. 52 53
      src/build_settings.cpp
  6. 22 28
      src/check_builtin.cpp
  7. 27 45
      src/check_decl.cpp
  8. 151 178
      src/check_expr.cpp
  9. 33 38
      src/check_stmt.cpp
  10. 42 42
      src/check_type.cpp
  11. 175 187
      src/checker.cpp
  12. 45 48
      src/checker.hpp
  13. 54 45
      src/common.cpp
  14. 39 39
      src/common_memory.cpp
  15. 13 23
      src/docs.cpp
  16. 2 2
      src/docs_format.cpp
  17. 51 53
      src/docs_writer.cpp
  18. 25 33
      src/entity.cpp
  19. 31 31
      src/error.cpp
  20. 84 94
      src/exact_value.cpp
  21. 77 77
      src/llvm_abi.cpp
  22. 130 157
      src/llvm_backend.cpp
  23. 138 137
      src/llvm_backend.hpp
  24. 30 30
      src/llvm_backend_const.cpp
  25. 21 27
      src/llvm_backend_debug.cpp
  26. 40 40
      src/llvm_backend_expr.cpp
  27. 89 157
      src/llvm_backend_general.cpp
  28. 26 26
      src/llvm_backend_opt.cpp
  29. 68 77
      src/llvm_backend_proc.cpp
  30. 44 54
      src/llvm_backend_stmt.cpp
  31. 10 10
      src/llvm_backend_type.cpp
  32. 95 107
      src/llvm_backend_utility.cpp
  33. 30 89
      src/main.cpp
  34. 20 20
      src/microsoft_craziness.h
  35. 113 145
      src/parser.cpp
  36. 53 47
      src/parser.hpp
  37. 2 4
      src/parser_pos.cpp
  38. 15 15
      src/path.cpp
  39. 7 7
      src/priority_queue.cpp
  40. 59 38
      src/ptr_map.cpp
  41. 44 23
      src/ptr_set.cpp
  42. 0 1030
      src/query_data.cpp
  43. 6 6
      src/queue.cpp
  44. 13 13
      src/range_cache.cpp
  45. 60 74
      src/string.cpp
  46. 58 37
      src/string_map.cpp
  47. 40 22
      src/string_set.cpp
  48. 28 27
      src/thread_pool.cpp
  49. 100 153
      src/threading.cpp
  50. 18 18
      src/timings.cpp
  51. 35 35
      src/tokenizer.cpp
  52. 145 193
      src/types.cpp
  53. 5 5
      src/unicode.cpp

+ 1 - 0
build.bat

@@ -62,6 +62,7 @@ if %release_mode% EQU 0 ( rem Debug
 set compiler_warnings= ^
 set compiler_warnings= ^
 	-W4 -WX ^
 	-W4 -WX ^
 	-wd4100 -wd4101 -wd4127 -wd4146 ^
 	-wd4100 -wd4101 -wd4127 -wd4146 ^
+	-wd4505 ^
 	-wd4456 -wd4457
 	-wd4456 -wd4457
 
 
 set compiler_includes= ^
 set compiler_includes= ^

+ 76 - 76
src/array.cpp

@@ -10,45 +10,45 @@ struct Array {
 
 
 	T &operator[](isize index) {
 	T &operator[](isize index) {
 		#if !defined(NO_ARRAY_BOUNDS_CHECK)
 		#if !defined(NO_ARRAY_BOUNDS_CHECK)
-			GB_ASSERT_MSG(0 <= index && index < count, "Index %td is out of bounds ranges 0..<%td", index, count);
+			GB_ASSERT_MSG(cast(usize)index < cast(usize)count, "Index %td is out of bounds ranges 0..<%td", index, count);
 		#endif
 		#endif
 		return data[index];
 		return data[index];
 	}
 	}
 
 
 	T const &operator[](isize index) const {
 	T const &operator[](isize index) const {
 		#if !defined(NO_ARRAY_BOUNDS_CHECK)
 		#if !defined(NO_ARRAY_BOUNDS_CHECK)
-			GB_ASSERT_MSG(0 <= index && index < count, "Index %td is out of bounds ranges 0..<%td", index, count);
+			GB_ASSERT_MSG(cast(usize)index < cast(usize)count, "Index %td is out of bounds ranges 0..<%td", index, count);
 		#endif
 		#endif
 		return data[index];
 		return data[index];
 	}
 	}
 };
 };
 
 
-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> void     array_free          (Array<T> *array);
-template <typename T> void     array_add           (Array<T> *array, T const &t);
-template <typename T> T *      array_add_and_get   (Array<T> *array);
-template <typename T> void     array_add_elems     (Array<T> *array, T const *elems, isize elem_count);
-template <typename T> T        array_pop           (Array<T> *array);
-template <typename T> void     array_clear         (Array<T> *array);
-template <typename T> void     array_reserve       (Array<T> *array, isize capacity);
-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> Array<T> array_slice         (Array<T> const &array, isize lo, isize hi);
-template <typename T> Array<T> array_clone         (gbAllocator const &a, Array<T> const &array);
+template <typename T> gb_internal void     array_init          (Array<T> *array, gbAllocator const &a);
+template <typename T> gb_internal void     array_init          (Array<T> *array, gbAllocator const &a, isize count);
+template <typename T> gb_internal void     array_init          (Array<T> *array, gbAllocator const &a, isize count, isize capacity);
+template <typename T> gb_internal Array<T> array_make          (gbAllocator const &a);
+template <typename T> gb_internal Array<T> array_make          (gbAllocator const &a, isize count);
+template <typename T> gb_internal Array<T> array_make          (gbAllocator const &a, isize count, isize capacity);
+template <typename T> gb_internal Array<T> array_make_from_ptr (T *data, isize count, isize capacity);
+template <typename T> gb_internal void     array_free          (Array<T> *array);
+template <typename T> gb_internal void     array_add           (Array<T> *array, T const &t);
+template <typename T> gb_internal T *      array_add_and_get   (Array<T> *array);
+template <typename T> gb_internal void     array_add_elems     (Array<T> *array, T const *elems, isize elem_count);
+template <typename T> gb_internal T        array_pop           (Array<T> *array);
+template <typename T> gb_internal void     array_clear         (Array<T> *array);
+template <typename T> gb_internal void     array_reserve       (Array<T> *array, isize capacity);
+template <typename T> gb_internal void     array_resize        (Array<T> *array, isize count);
+template <typename T> gb_internal void     array_set_capacity  (Array<T> *array, isize capacity);
+template <typename T> gb_internal Array<T> array_slice         (Array<T> const &array, isize lo, isize hi);
+template <typename T> gb_internal Array<T> array_clone         (gbAllocator const &a, Array<T> const &array);
 
 
-template <typename T> void array_ordered_remove  (Array<T> *array, isize index);
-template <typename T> void array_unordered_remove(Array<T> *array, isize index);
+template <typename T> gb_internal void array_ordered_remove  (Array<T> *array, isize index);
+template <typename T> gb_internal void array_unordered_remove(Array<T> *array, isize index);
 
 
-template <typename T> void array_copy(Array<T> *array, Array<T> const &data, isize offset);
-template <typename T> void array_copy(Array<T> *array, Array<T> const &data, isize offset, isize count);
+template <typename T> gb_internal void array_copy(Array<T> *array, Array<T> const &data, isize offset);
+template <typename T> gb_internal void array_copy(Array<T> *array, Array<T> const &data, isize offset, isize count);
 
 
-template <typename T> T *array_end_ptr(Array<T> *array);
+template <typename T> gb_internal T *array_end_ptr(Array<T> *array);
 
 
 
 
 template <typename T>
 template <typename T>
@@ -56,27 +56,27 @@ struct Slice {
 	T *data;
 	T *data;
 	isize count;
 	isize count;
 
 
-	T &operator[](isize index) {
+	gb_inline T &operator[](isize index) {
 		#if !defined(NO_ARRAY_BOUNDS_CHECK)
 		#if !defined(NO_ARRAY_BOUNDS_CHECK)
-			GB_ASSERT_MSG(0 <= index && index < count, "Index %td is out of bounds ranges 0..<%td", index, count);
+			GB_ASSERT_MSG(cast(usize)index < cast(usize)count, "Index %td is out of bounds ranges 0..<%td", index, count);
 		#endif
 		#endif
 		return data[index];
 		return data[index];
 	}
 	}
 
 
-	T const &operator[](isize index) const {
+	gb_inline T const &operator[](isize index) const {
 		#if !defined(NO_ARRAY_BOUNDS_CHECK)
 		#if !defined(NO_ARRAY_BOUNDS_CHECK)
-			GB_ASSERT_MSG(0 <= index && index < count, "Index %td is out of bounds ranges 0..<%td", index, count);
+			GB_ASSERT_MSG(cast(usize)index < cast(usize)count, "Index %td is out of bounds ranges 0..<%td", index, count);
 		#endif
 		#endif
 		return data[index];
 		return data[index];
 	}
 	}
 };
 };
 
 
-template <typename T> Slice<T> slice_from_array(Array<T> const &a);
+template <typename T> gb_internal Slice<T> slice_from_array(Array<T> const &a);
 
 
 
 
 
 
 template <typename T>
 template <typename T>
-Slice<T> slice_make(gbAllocator const &allocator, isize count) {
+gb_internal Slice<T> slice_make(gbAllocator const &allocator, isize count) {
 	GB_ASSERT(count >= 0);
 	GB_ASSERT(count >= 0);
 	Slice<T> s = {};
 	Slice<T> s = {};
 	s.data = gb_alloc_array(allocator, T, count);
 	s.data = gb_alloc_array(allocator, T, count);
@@ -86,7 +86,7 @@ Slice<T> slice_make(gbAllocator const &allocator, isize count) {
 }
 }
 
 
 template <typename T>
 template <typename T>
-void slice_init(Slice<T> *s, gbAllocator const &allocator, isize count) {
+gb_internal void slice_init(Slice<T> *s, gbAllocator const &allocator, isize count) {
 	GB_ASSERT(count >= 0);
 	GB_ASSERT(count >= 0);
 	s->data = gb_alloc_array(allocator, T, count);
 	s->data = gb_alloc_array(allocator, T, count);
 	if (count > 0) {
 	if (count > 0) {
@@ -96,23 +96,23 @@ void slice_init(Slice<T> *s, gbAllocator const &allocator, isize count) {
 }
 }
 
 
 template <typename T>
 template <typename T>
-void slice_free(Slice<T> *s, gbAllocator const &allocator) {
+gb_internal void slice_free(Slice<T> *s, gbAllocator const &allocator) {
 	gb_free(allocator, s->data);
 	gb_free(allocator, s->data);
 }
 }
 
 
 template <typename T>
 template <typename T>
-void slice_resize(Slice<T> *s, gbAllocator const &allocator, isize new_count) {
+gb_internal void slice_resize(Slice<T> *s, gbAllocator const &allocator, isize new_count) {
 	resize_array_raw(&s->data, allocator, s->count, new_count);
 	resize_array_raw(&s->data, allocator, s->count, new_count);
 	s->count = new_count;
 	s->count = new_count;
 }
 }
 
 
 
 
 template <typename T>
 template <typename T>
-Slice<T> slice_from_array(Array<T> const &a) {
+gb_internal Slice<T> slice_from_array(Array<T> const &a) {
 	return {a.data, a.count};
 	return {a.data, a.count};
 }
 }
 template <typename T>
 template <typename T>
-Slice<T> slice_array(Array<T> const &array, isize lo, isize hi) {
+gb_internal Slice<T> slice_array(Array<T> const &array, isize lo, isize hi) {
 	GB_ASSERT(0 <= lo && lo <= hi && hi <= array.count);
 	GB_ASSERT(0 <= lo && lo <= hi && hi <= array.count);
 	Slice<T> out = {};
 	Slice<T> out = {};
 	isize len = hi-lo;
 	isize len = hi-lo;
@@ -125,30 +125,30 @@ Slice<T> slice_array(Array<T> const &array, isize lo, isize hi) {
 
 
 
 
 template <typename T>
 template <typename T>
-Slice<T> slice_clone(gbAllocator const &allocator, Slice<T> const &a) {
+gb_internal Slice<T> slice_clone(gbAllocator const &allocator, Slice<T> const &a) {
 	T *data = cast(T *)gb_alloc_copy_align(allocator, a.data, a.count*gb_size_of(T), gb_align_of(T));
 	T *data = cast(T *)gb_alloc_copy_align(allocator, a.data, a.count*gb_size_of(T), gb_align_of(T));
 	return {data, a.count};
 	return {data, a.count};
 }
 }
 
 
 template <typename T>
 template <typename T>
-Slice<T> slice_clone_from_array(gbAllocator const &allocator, Array<T> const &a) {
+gb_internal Slice<T> slice_clone_from_array(gbAllocator const &allocator, Array<T> const &a) {
 	auto c = array_clone(allocator, a);
 	auto c = array_clone(allocator, a);
 	return {c.data, c.count};
 	return {c.data, c.count};
 }
 }
 
 
 
 
 template <typename T>
 template <typename T>
-void slice_copy(Slice<T> *slice, Slice<T> const &data) {
+gb_internal void slice_copy(Slice<T> *slice, Slice<T> const &data) {
 	isize n = gb_min(slice->count, data.count);
 	isize n = gb_min(slice->count, data.count);
 	gb_memmove(slice->data, data.data, gb_size_of(T)*n);
 	gb_memmove(slice->data, data.data, gb_size_of(T)*n);
 }
 }
 template <typename T>
 template <typename T>
-void slice_copy(Slice<T> *slice, Slice<T> const &data, isize offset) {
+gb_internal void slice_copy(Slice<T> *slice, Slice<T> const &data, isize offset) {
 	isize n = gb_clamp(slice->count-offset, 0, data.count);
 	isize n = gb_clamp(slice->count-offset, 0, data.count);
 	gb_memmove(slice->data+offset, data.data, gb_size_of(T)*n);
 	gb_memmove(slice->data+offset, data.data, gb_size_of(T)*n);
 }
 }
 template <typename T>
 template <typename T>
-void slice_copy(Slice<T> *slice, Slice<T> const &data, isize offset, isize count) {
+gb_internal void slice_copy(Slice<T> *slice, Slice<T> const &data, isize offset, isize count) {
 	isize n = gb_clamp(slice->count-offset, 0, gb_min(data.count, count));
 	isize n = gb_clamp(slice->count-offset, 0, gb_min(data.count, count));
 	gb_memmove(slice->data+offset, data.data, gb_size_of(T)*n);
 	gb_memmove(slice->data+offset, data.data, gb_size_of(T)*n);
 }
 }
@@ -156,7 +156,7 @@ void slice_copy(Slice<T> *slice, Slice<T> const &data, isize offset, isize count
 
 
 
 
 template <typename T>
 template <typename T>
-gb_inline Slice<T> slice(Slice<T> const &array, isize lo, isize hi) {
+gb_internal gb_inline Slice<T> slice(Slice<T> const &array, isize lo, isize hi) {
 	GB_ASSERT(0 <= lo && lo <= hi && hi <= array.count);
 	GB_ASSERT(0 <= lo && lo <= hi && hi <= array.count);
 	Slice<T> out = {};
 	Slice<T> out = {};
 	isize len = hi-lo;
 	isize len = hi-lo;
@@ -169,7 +169,7 @@ gb_inline Slice<T> slice(Slice<T> const &array, isize lo, isize hi) {
 
 
 
 
 template <typename T>
 template <typename T>
-void slice_ordered_remove(Slice<T> *array, isize index) {
+gb_internal void slice_ordered_remove(Slice<T> *array, isize index) {
 	GB_ASSERT(0 <= index && index < array->count);
 	GB_ASSERT(0 <= index && index < array->count);
 
 
 	isize bytes = gb_size_of(T) * (array->count-(index+1));
 	isize bytes = gb_size_of(T) * (array->count-(index+1));
@@ -178,7 +178,7 @@ void slice_ordered_remove(Slice<T> *array, isize index) {
 }
 }
 
 
 template <typename T>
 template <typename T>
-void slice_unordered_remove(Slice<T> *array, isize index) {
+gb_internal void slice_unordered_remove(Slice<T> *array, isize index) {
 	GB_ASSERT(0 <= index && index < array->count);
 	GB_ASSERT(0 <= index && index < array->count);
 
 
 	isize n = array->count-1;
 	isize n = array->count-1;
@@ -190,18 +190,18 @@ void slice_unordered_remove(Slice<T> *array, isize index) {
 
 
 
 
 template <typename T>
 template <typename T>
-void array_copy(Array<T> *array, Array<T> const &data, isize offset) {
+gb_internal void array_copy(Array<T> *array, Array<T> const &data, isize offset) {
 	gb_memmove(array->data+offset, data.data, gb_size_of(T)*data.count);
 	gb_memmove(array->data+offset, data.data, gb_size_of(T)*data.count);
 }
 }
 template <typename T>
 template <typename T>
-void array_copy(Array<T> *array, Array<T> const &data, isize offset, isize count) {
+gb_internal void array_copy(Array<T> *array, Array<T> const &data, isize offset, isize count) {
 	gb_memmove(array->data+offset, data.data, gb_size_of(T)*gb_min(data.count, count));
 	gb_memmove(array->data+offset, data.data, gb_size_of(T)*gb_min(data.count, count));
 }
 }
 
 
 
 
 
 
 template <typename T>
 template <typename T>
-T *array_end_ptr(Array<T> *array) {
+gb_internal T *array_end_ptr(Array<T> *array) {
 	if (array->count > 0) {
 	if (array->count > 0) {
 		return &array->data[array->count-1];
 		return &array->data[array->count-1];
 	}
 	}
@@ -210,18 +210,18 @@ T *array_end_ptr(Array<T> *array) {
 
 
 
 
 template <typename T>
 template <typename T>
-gb_inline void array_init(Array<T> *array, gbAllocator const &a) {
+gb_internal gb_inline void array_init(Array<T> *array, gbAllocator const &a) {
 	isize cap = ARRAY_GROW_FORMULA(0);
 	isize cap = ARRAY_GROW_FORMULA(0);
 	array_init(array, a, 0, cap);
 	array_init(array, a, 0, cap);
 }
 }
 
 
 template <typename T>
 template <typename T>
-gb_inline void array_init(Array<T> *array, gbAllocator const &a, isize count) {
+gb_internal gb_inline void array_init(Array<T> *array, gbAllocator const &a, isize count) {
 	array_init(array, a, count, count);
 	array_init(array, a, count, count);
 }
 }
 
 
 template <typename T>
 template <typename T>
-gb_inline void array_init(Array<T> *array, gbAllocator const &a, isize count, isize capacity) {
+gb_internal gb_inline void array_init(Array<T> *array, gbAllocator const &a, isize count, isize capacity) {
 	array->allocator = a;
 	array->allocator = a;
 	array->data = nullptr;
 	array->data = nullptr;
 	if (capacity > 0) {
 	if (capacity > 0) {
@@ -234,7 +234,7 @@ gb_inline void array_init(Array<T> *array, gbAllocator const &a, isize count, is
 
 
 
 
 template <typename T>
 template <typename T>
-gb_inline Array<T> array_make_from_ptr(T *data, isize count, isize capacity) {
+gb_internal 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;
@@ -244,7 +244,7 @@ gb_inline Array<T> array_make_from_ptr(T *data, isize count, isize capacity) {
 
 
 
 
 template <typename T>
 template <typename T>
-gb_inline Array<T> array_make(gbAllocator const &a) {
+gb_internal gb_inline Array<T> array_make(gbAllocator const &a) {
 	isize capacity = ARRAY_GROW_FORMULA(0);
 	isize capacity = ARRAY_GROW_FORMULA(0);
 	Array<T> array = {};
 	Array<T> array = {};
 	array.allocator = a;
 	array.allocator = a;
@@ -254,7 +254,7 @@ gb_inline Array<T> array_make(gbAllocator const &a) {
 	return array;
 	return array;
 }
 }
 template <typename T>
 template <typename T>
-gb_inline Array<T> array_make(gbAllocator const &a, isize count) {
+gb_internal gb_inline Array<T> array_make(gbAllocator const &a, isize count) {
 	Array<T> array = {};
 	Array<T> array = {};
 	array.allocator = a;
 	array.allocator = a;
 	array.data = gb_alloc_array(a, T, count);
 	array.data = gb_alloc_array(a, T, count);
@@ -263,7 +263,7 @@ gb_inline Array<T> array_make(gbAllocator const &a, isize count) {
 	return array;
 	return array;
 }
 }
 template <typename T>
 template <typename T>
-gb_inline Array<T> array_make(gbAllocator const &a, isize count, isize capacity) {
+gb_internal gb_inline Array<T> array_make(gbAllocator const &a, isize count, isize capacity) {
 	Array<T> array = {};
 	Array<T> array = {};
 	array.allocator = a;
 	array.allocator = a;
 	array.data = gb_alloc_array(a, T, capacity);
 	array.data = gb_alloc_array(a, T, capacity);
@@ -275,7 +275,7 @@ gb_inline Array<T> array_make(gbAllocator const &a, isize count, isize capacity)
 
 
 
 
 template <typename T>
 template <typename T>
-gb_inline void array_free(Array<T> *array) {
+gb_internal gb_inline void array_free(Array<T> *array) {
 	if (array->allocator.proc != nullptr) {
 	if (array->allocator.proc != nullptr) {
 		gb_free(array->allocator, array->data);
 		gb_free(array->allocator, array->data);
 	}
 	}
@@ -284,7 +284,7 @@ gb_inline void array_free(Array<T> *array) {
 }
 }
 
 
 template <typename T>
 template <typename T>
-void array__grow(Array<T> *array, isize min_capacity) {
+gb_internal void array__grow(Array<T> *array, isize min_capacity) {
 	isize new_capacity = ARRAY_GROW_FORMULA(array->capacity);
 	isize new_capacity = ARRAY_GROW_FORMULA(array->capacity);
 	if (new_capacity < min_capacity) {
 	if (new_capacity < min_capacity) {
 		new_capacity = min_capacity;
 		new_capacity = min_capacity;
@@ -293,7 +293,7 @@ void array__grow(Array<T> *array, isize min_capacity) {
 }
 }
 
 
 template <typename T>
 template <typename T>
-void array_add(Array<T> *array, T const &t) {
+gb_internal void array_add(Array<T> *array, T const &t) {
 	if (array->capacity < array->count+1) {
 	if (array->capacity < array->count+1) {
 		array__grow(array, 0);
 		array__grow(array, 0);
 	}
 	}
@@ -302,7 +302,7 @@ void array_add(Array<T> *array, T const &t) {
 }
 }
 
 
 template <typename T>
 template <typename T>
-T *array_add_and_get(Array<T> *array) {
+gb_internal T *array_add_and_get(Array<T> *array) {
 	if (array->count < array->capacity) {
 	if (array->count < array->capacity) {
 		return &array->data[array->count++];
 		return &array->data[array->count++];
 	}
 	}
@@ -314,7 +314,7 @@ T *array_add_and_get(Array<T> *array) {
 
 
 
 
 template <typename T>
 template <typename T>
-void array_add_elems(Array<T> *array, T const *elems, isize elem_count) {
+gb_internal void array_add_elems(Array<T> *array, T const *elems, isize elem_count) {
 	GB_ASSERT(elem_count >= 0);
 	GB_ASSERT(elem_count >= 0);
 	if (array->capacity < array->count+elem_count) {
 	if (array->capacity < array->count+elem_count) {
 		array__grow(array, array->count+elem_count);
 		array__grow(array, array->count+elem_count);
@@ -325,26 +325,26 @@ void array_add_elems(Array<T> *array, T const *elems, isize elem_count) {
 
 
 
 
 template <typename T>
 template <typename T>
-gb_inline T array_pop(Array<T> *array) {
+gb_internal gb_inline T array_pop(Array<T> *array) {
 	GB_ASSERT(array->count > 0);
 	GB_ASSERT(array->count > 0);
 	array->count--;
 	array->count--;
 	return array->data[array->count];
 	return array->data[array->count];
 }
 }
 
 
 template <typename T>
 template <typename T>
-void array_clear(Array<T> *array) {
+gb_internal void array_clear(Array<T> *array) {
 	array->count = 0;
 	array->count = 0;
 }
 }
 
 
 template <typename T>
 template <typename T>
-void array_reserve(Array<T> *array, isize capacity) {
+gb_internal void array_reserve(Array<T> *array, isize capacity) {
 	if (array->capacity < capacity) {
 	if (array->capacity < capacity) {
 		array_set_capacity(array, capacity);
 		array_set_capacity(array, capacity);
 	}
 	}
 }
 }
 
 
 template <typename T>
 template <typename T>
-void array_resize(Array<T> *array, isize count) {
+gb_internal void array_resize(Array<T> *array, isize count) {
 	if (array->capacity < count) {
 	if (array->capacity < count) {
 		array__grow(array, count);
 		array__grow(array, count);
 	}
 	}
@@ -352,7 +352,7 @@ void array_resize(Array<T> *array, isize count) {
 }
 }
 
 
 template <typename T>
 template <typename T>
-void array_set_capacity(Array<T> *array, isize capacity) {
+gb_internal void array_set_capacity(Array<T> *array, isize capacity) {
 	if (capacity == array->capacity) {
 	if (capacity == array->capacity) {
 		return;
 		return;
 	}
 	}
@@ -381,7 +381,7 @@ void array_set_capacity(Array<T> *array, isize capacity) {
 
 
 
 
 template <typename T>
 template <typename T>
-gb_inline Array<T> array_slice(Array<T> const &array, isize lo, isize hi) {
+gb_internal gb_inline Array<T> array_slice(Array<T> const &array, isize lo, isize hi) {
 	GB_ASSERT(0 <= lo && lo <= hi && hi <= array.count);
 	GB_ASSERT(0 <= lo && lo <= hi && hi <= array.count);
 	Array<T> out = {};
 	Array<T> out = {};
 	isize len = hi-lo;
 	isize len = hi-lo;
@@ -394,7 +394,7 @@ gb_inline Array<T> array_slice(Array<T> const &array, isize lo, isize hi) {
 }
 }
 
 
 template <typename T>
 template <typename T>
-Array<T> array_clone(gbAllocator const &allocator, Array<T> const &array) {
+gb_internal Array<T> array_clone(gbAllocator const &allocator, Array<T> const &array) {
 	auto clone = array_make<T>(allocator, array.count, array.count);
 	auto clone = array_make<T>(allocator, array.count, array.count);
 	array_copy(&clone, array, 0);
 	array_copy(&clone, array, 0);
 	return clone;
 	return clone;
@@ -402,7 +402,7 @@ Array<T> array_clone(gbAllocator const &allocator, Array<T> const &array) {
 
 
 
 
 template <typename T>
 template <typename T>
-void array_ordered_remove(Array<T> *array, isize index) {
+gb_internal void array_ordered_remove(Array<T> *array, isize index) {
 	GB_ASSERT(0 <= index && index < array->count);
 	GB_ASSERT(0 <= index && index < array->count);
 
 
 	isize bytes = gb_size_of(T) * (array->count-(index+1));
 	isize bytes = gb_size_of(T) * (array->count-(index+1));
@@ -411,7 +411,7 @@ void array_ordered_remove(Array<T> *array, isize index) {
 }
 }
 
 
 template <typename T>
 template <typename T>
-void array_unordered_remove(Array<T> *array, isize index) {
+gb_internal void array_unordered_remove(Array<T> *array, isize index) {
 	GB_ASSERT(0 <= index && index < array->count);
 	GB_ASSERT(0 <= index && index < array->count);
 
 
 	isize n = array->count-1;
 	isize n = array->count-1;
@@ -424,35 +424,35 @@ void array_unordered_remove(Array<T> *array, isize index) {
 
 
 
 
 template <typename T>
 template <typename T>
-T *begin(Array<T> &array) {
+gb_internal T *begin(Array<T> &array) {
 	return array.data;
 	return array.data;
 }
 }
 template <typename T>
 template <typename T>
-T const *begin(Array<T> const &array) {
+gb_internal T const *begin(Array<T> const &array) {
 	return array.data;
 	return array.data;
 }
 }
 template <typename T>
 template <typename T>
-T *end(Array<T> &array) {
+gb_internal T *end(Array<T> &array) {
 	return array.data + array.count;
 	return array.data + array.count;
 }
 }
 template <typename T>
 template <typename T>
-T const *end(Array<T> const &array) {
+gb_internal T const *end(Array<T> const &array) {
 	return array.data + array.count;
 	return array.data + array.count;
 }
 }
 
 
 template <typename T>
 template <typename T>
-T *begin(Slice<T> &array) {
+gb_internal T *begin(Slice<T> &array) {
 	return array.data;
 	return array.data;
 }
 }
 template <typename T>
 template <typename T>
-T const *begin(Slice<T> const &array) {
+gb_internal T const *begin(Slice<T> const &array) {
 	return array.data;
 	return array.data;
 }
 }
 template <typename T>
 template <typename T>
-T *end(Slice<T> &array) {
+gb_internal T *end(Slice<T> &array) {
 	return array.data + array.count;
 	return array.data + array.count;
 }
 }
 template <typename T>
 template <typename T>
-T const *end(Slice<T> const &array) {
+gb_internal T const *end(Slice<T> const &array) {
 	return array.data + array.count;
 	return array.data + array.count;
 }
 }

+ 79 - 79
src/big_int.cpp

@@ -37,86 +37,86 @@ void MP_FREE(void *mem, size_t size) {
 
 
 typedef mp_int BigInt;
 typedef mp_int BigInt;
 
 
-void big_int_from_u64(BigInt *dst, u64 x);
-void big_int_from_i64(BigInt *dst, i64 x);
-void big_int_init    (BigInt *dst, BigInt const *src);
-void big_int_from_string(BigInt *dst, String const &s, bool *success);
+gb_internal void big_int_from_u64(BigInt *dst, u64 x);
+gb_internal void big_int_from_i64(BigInt *dst, i64 x);
+gb_internal void big_int_init    (BigInt *dst, BigInt const *src);
+gb_internal void big_int_from_string(BigInt *dst, String const &s, bool *success);
 
 
-void big_int_dealloc(BigInt *dst) {
+gb_internal void big_int_dealloc(BigInt *dst) {
 	mp_clear(dst);
 	mp_clear(dst);
 }
 }
 
 
-BigInt big_int_make(BigInt const *b, bool abs=false);
-BigInt big_int_make_abs(BigInt const *b);
-BigInt big_int_make_u64(u64 x);
-BigInt big_int_make_i64(i64 x);
+gb_internal BigInt big_int_make(BigInt const *b, bool abs=false);
+gb_internal BigInt big_int_make_abs(BigInt const *b);
+gb_internal BigInt big_int_make_u64(u64 x);
+gb_internal BigInt big_int_make_i64(i64 x);
 
 
-u64    big_int_to_u64   (BigInt const *x);
-i64    big_int_to_i64   (BigInt const *x);
-f64    big_int_to_f64   (BigInt const *x);
-String big_int_to_string(gbAllocator allocator, BigInt const *x, u64 base = 10);
+gb_internal u64    big_int_to_u64   (BigInt const *x);
+gb_internal i64    big_int_to_i64   (BigInt const *x);
+gb_internal f64    big_int_to_f64   (BigInt const *x);
+gb_internal String big_int_to_string(gbAllocator allocator, BigInt const *x, u64 base = 10);
 
 
-void big_int_add    (BigInt *dst, BigInt const *x, BigInt const *y);
-void big_int_sub    (BigInt *dst, BigInt const *x, BigInt const *y);
-void big_int_shl    (BigInt *dst, BigInt const *x, BigInt const *y);
-void big_int_shr    (BigInt *dst, BigInt const *x, BigInt const *y);
-void big_int_mul    (BigInt *dst, BigInt const *x, BigInt const *y);
-void big_int_mul_u64(BigInt *dst, BigInt const *x, u64 y);
+gb_internal void big_int_add    (BigInt *dst, BigInt const *x, BigInt const *y);
+gb_internal void big_int_sub    (BigInt *dst, BigInt const *x, BigInt const *y);
+gb_internal void big_int_shl    (BigInt *dst, BigInt const *x, BigInt const *y);
+gb_internal void big_int_shr    (BigInt *dst, BigInt const *x, BigInt const *y);
+gb_internal void big_int_mul    (BigInt *dst, BigInt const *x, BigInt const *y);
+gb_internal void big_int_mul_u64(BigInt *dst, BigInt const *x, u64 y);
 
 
-void big_int_quo_rem(BigInt const *x, BigInt const *y, BigInt *q, BigInt *r);
-void big_int_quo    (BigInt *z, BigInt const *x, BigInt const *y);
-void big_int_rem    (BigInt *z, BigInt const *x, BigInt const *y);
+gb_internal void big_int_quo_rem(BigInt const *x, BigInt const *y, BigInt *q, BigInt *r);
+gb_internal void big_int_quo    (BigInt *z, BigInt const *x, BigInt const *y);
+gb_internal void big_int_rem    (BigInt *z, BigInt const *x, BigInt const *y);
 
 
-void big_int_and    (BigInt *dst, BigInt const *x, BigInt const *y);
-void big_int_and_not(BigInt *dst, BigInt const *x, BigInt const *y);
-void big_int_xor    (BigInt *dst, BigInt const *x, BigInt const *y);
-void big_int_or     (BigInt *dst, BigInt const *x, BigInt const *y);
-void big_int_not    (BigInt *dst, BigInt const *x, i32 bit_count, bool is_signed);
+gb_internal void big_int_and    (BigInt *dst, BigInt const *x, BigInt const *y);
+gb_internal void big_int_and_not(BigInt *dst, BigInt const *x, BigInt const *y);
+gb_internal void big_int_xor    (BigInt *dst, BigInt const *x, BigInt const *y);
+gb_internal void big_int_or     (BigInt *dst, BigInt const *x, BigInt const *y);
+gb_internal void big_int_not    (BigInt *dst, BigInt const *x, i32 bit_count, bool is_signed);
 
 
 
 
-void big_int_add_eq(BigInt *dst, BigInt const *x);
-void big_int_sub_eq(BigInt *dst, BigInt const *x);
-void big_int_shl_eq(BigInt *dst, BigInt const *x);
-void big_int_shr_eq(BigInt *dst, BigInt const *x);
-void big_int_mul_eq(BigInt *dst, BigInt const *x);
+gb_internal void big_int_add_eq(BigInt *dst, BigInt const *x);
+gb_internal void big_int_sub_eq(BigInt *dst, BigInt const *x);
+gb_internal void big_int_shl_eq(BigInt *dst, BigInt const *x);
+gb_internal void big_int_shr_eq(BigInt *dst, BigInt const *x);
+gb_internal void big_int_mul_eq(BigInt *dst, BigInt const *x);
 
 
-void big_int_quo_eq(BigInt *dst, BigInt const *x);
-void big_int_rem_eq(BigInt *dst, BigInt const *x);
+gb_internal void big_int_quo_eq(BigInt *dst, BigInt const *x);
+gb_internal void big_int_rem_eq(BigInt *dst, BigInt const *x);
 
 
-bool big_int_is_neg(BigInt const *x);
-void big_int_neg(BigInt *dst, BigInt const *x);
+gb_internal bool big_int_is_neg(BigInt const *x);
+gb_internal void big_int_neg(BigInt *dst, BigInt const *x);
 
 
-void big_int_add_eq(BigInt *dst, BigInt const *x) {
+gb_internal void big_int_add_eq(BigInt *dst, BigInt const *x) {
 	BigInt res = {};
 	BigInt res = {};
 	big_int_init(&res, dst);
 	big_int_init(&res, dst);
 	big_int_add(dst, &res, x);
 	big_int_add(dst, &res, x);
 }
 }
-void big_int_sub_eq(BigInt *dst, BigInt const *x) {
+gb_internal void big_int_sub_eq(BigInt *dst, BigInt const *x) {
 	BigInt res = {};
 	BigInt res = {};
 	big_int_init(&res, dst);
 	big_int_init(&res, dst);
 	big_int_sub(dst, &res, x);
 	big_int_sub(dst, &res, x);
 }
 }
-void big_int_shl_eq(BigInt *dst, BigInt const *x) {
+gb_internal void big_int_shl_eq(BigInt *dst, BigInt const *x) {
 	BigInt res = {};
 	BigInt res = {};
 	big_int_init(&res, dst);
 	big_int_init(&res, dst);
 	big_int_shl(dst, &res, x);
 	big_int_shl(dst, &res, x);
 }
 }
-void big_int_shr_eq(BigInt *dst, BigInt const *x) {
+gb_internal void big_int_shr_eq(BigInt *dst, BigInt const *x) {
 	BigInt res = {};
 	BigInt res = {};
 	big_int_init(&res, dst);
 	big_int_init(&res, dst);
 	big_int_shr(dst, &res, x);
 	big_int_shr(dst, &res, x);
 }
 }
-void big_int_mul_eq(BigInt *dst, BigInt const *x) {
+gb_internal void big_int_mul_eq(BigInt *dst, BigInt const *x) {
 	BigInt res = {};
 	BigInt res = {};
 	big_int_init(&res, dst);
 	big_int_init(&res, dst);
 	big_int_mul(dst, &res, x);
 	big_int_mul(dst, &res, x);
 }
 }
-void big_int_quo_eq(BigInt *dst, BigInt const *x) {
+gb_internal void big_int_quo_eq(BigInt *dst, BigInt const *x) {
 	BigInt res = {};
 	BigInt res = {};
 	big_int_init(&res, dst);
 	big_int_init(&res, dst);
 	big_int_quo(dst, &res, x);
 	big_int_quo(dst, &res, x);
 }
 }
-void big_int_rem_eq(BigInt *dst, BigInt const *x) {
+gb_internal void big_int_rem_eq(BigInt *dst, BigInt const *x) {
 	BigInt res = {};
 	BigInt res = {};
 	big_int_init(&res, dst);
 	big_int_init(&res, dst);
 	big_int_rem(dst, &res, x);
 	big_int_rem(dst, &res, x);
@@ -124,7 +124,7 @@ void big_int_rem_eq(BigInt *dst, BigInt const *x) {
 
 
 
 
 
 
-i64 big_int_sign(BigInt const *x) {
+gb_internal i64 big_int_sign(BigInt const *x) {
 	if (mp_iszero(x)) {
 	if (mp_iszero(x)) {
 		return 0;
 		return 0;
 	}
 	}
@@ -132,44 +132,44 @@ i64 big_int_sign(BigInt const *x) {
 }
 }
 
 
 
 
-void big_int_from_u64(BigInt *dst, u64 x) {
+gb_internal void big_int_from_u64(BigInt *dst, u64 x) {
 	mp_init_u64(dst, x);
 	mp_init_u64(dst, x);
 }
 }
-void big_int_from_i64(BigInt *dst, i64 x) {
+gb_internal void big_int_from_i64(BigInt *dst, i64 x) {
 	mp_init_i64(dst, x);
 	mp_init_i64(dst, x);
 
 
 }
 }
-void big_int_init(BigInt *dst, BigInt const *src) {
+gb_internal void big_int_init(BigInt *dst, BigInt const *src) {
 	if (dst == src) {
 	if (dst == src) {
 		return;
 		return;
 	}
 	}
 	mp_init_copy(dst, src);
 	mp_init_copy(dst, src);
 }
 }
 
 
-BigInt big_int_make(BigInt const *b, bool abs) {
+gb_internal BigInt big_int_make(BigInt const *b, bool abs) {
 	BigInt i = {};
 	BigInt i = {};
 	big_int_init(&i, b);
 	big_int_init(&i, b);
 	if (abs) mp_abs(&i, &i);
 	if (abs) mp_abs(&i, &i);
 	return i;
 	return i;
 }
 }
-BigInt big_int_make_abs(BigInt const *b) {
+gb_internal BigInt big_int_make_abs(BigInt const *b) {
 	return big_int_make(b, true);
 	return big_int_make(b, true);
 }
 }
 
 
 
 
-BigInt big_int_make_u64(u64 x) {
+gb_internal BigInt big_int_make_u64(u64 x) {
 	BigInt i = {};
 	BigInt i = {};
 	big_int_from_u64(&i, x);
 	big_int_from_u64(&i, x);
 	return i;
 	return i;
 }
 }
-BigInt big_int_make_i64(i64 x) {
+gb_internal BigInt big_int_make_i64(i64 x) {
 	BigInt i = {};
 	BigInt i = {};
 	big_int_from_i64(&i, x);
 	big_int_from_i64(&i, x);
 	return i;
 	return i;
 }
 }
 
 
 
 
-void big_int_from_string(BigInt *dst, String const &s, bool *success) {
+gb_internal void big_int_from_string(BigInt *dst, String const &s, bool *success) {
 	*success = true;
 	*success = true;
 
 
 	bool is_negative = false;
 	bool is_negative = false;
@@ -262,66 +262,66 @@ void big_int_from_string(BigInt *dst, String const &s, bool *success) {
 
 
 
 
 
 
-u64 big_int_to_u64(BigInt const *x) {
+gb_internal u64 big_int_to_u64(BigInt const *x) {
 	GB_ASSERT(x->sign == 0);
 	GB_ASSERT(x->sign == 0);
 	return mp_get_u64(x);
 	return mp_get_u64(x);
 }
 }
 
 
-i64 big_int_to_i64(BigInt const *x) {
+gb_internal i64 big_int_to_i64(BigInt const *x) {
 	return mp_get_i64(x);
 	return mp_get_i64(x);
 }
 }
 
 
-f64 big_int_to_f64(BigInt const *x) {
+gb_internal f64 big_int_to_f64(BigInt const *x) {
 	return mp_get_double(x);
 	return mp_get_double(x);
 }
 }
 
 
 
 
-void big_int_neg(BigInt *dst, BigInt const *x) {
+gb_internal void big_int_neg(BigInt *dst, BigInt const *x) {
 	mp_neg(x, dst);
 	mp_neg(x, dst);
 }
 }
 
 
 
 
-int big_int_cmp(BigInt const *x, BigInt const *y) {
+gb_internal int big_int_cmp(BigInt const *x, BigInt const *y) {
 	return mp_cmp(x, y);
 	return mp_cmp(x, y);
 }
 }
 
 
-int big_int_cmp_zero(BigInt const *x) {
+gb_internal int big_int_cmp_zero(BigInt const *x) {
 	if (mp_iszero(x)) {
 	if (mp_iszero(x)) {
 		return 0;
 		return 0;
 	}
 	}
 	return x->sign ? -1 : +1;
 	return x->sign ? -1 : +1;
 }
 }
 
 
-bool big_int_is_zero(BigInt const *x) {
+gb_internal bool big_int_is_zero(BigInt const *x) {
 	return mp_iszero(x);
 	return mp_iszero(x);
 }
 }
 
 
 
 
 
 
 
 
-void big_int_add(BigInt *dst, BigInt const *x, BigInt const *y) {
+gb_internal void big_int_add(BigInt *dst, BigInt const *x, BigInt const *y) {
 	mp_add(x, y, dst);
 	mp_add(x, y, dst);
 }
 }
 
 
 
 
-void big_int_sub(BigInt *dst, BigInt const *x, BigInt const *y) {
+gb_internal void big_int_sub(BigInt *dst, BigInt const *x, BigInt const *y) {
 	mp_sub(x, y, dst);
 	mp_sub(x, y, dst);
 }
 }
 
 
 
 
-void big_int_shl(BigInt *dst, BigInt const *x, BigInt const *y) {
+gb_internal void big_int_shl(BigInt *dst, BigInt const *x, BigInt const *y) {
 	u32 yy = mp_get_u32(y);
 	u32 yy = mp_get_u32(y);
 	mp_mul_2d(x, yy, dst);
 	mp_mul_2d(x, yy, dst);
 }
 }
 
 
-void big_int_shr(BigInt *dst, BigInt const *x, BigInt const *y) {
+gb_internal void big_int_shr(BigInt *dst, BigInt const *x, BigInt const *y) {
 	u32 yy = mp_get_u32(y);
 	u32 yy = mp_get_u32(y);
 	BigInt d = {};
 	BigInt d = {};
 	mp_div_2d(x, yy, dst, &d);
 	mp_div_2d(x, yy, dst, &d);
 	big_int_dealloc(&d);
 	big_int_dealloc(&d);
 }
 }
 
 
-void big_int_mul_u64(BigInt *dst, BigInt const *x, u64 y) {
+gb_internal void big_int_mul_u64(BigInt *dst, BigInt const *x, u64 y) {
 	BigInt d = {};
 	BigInt d = {};
 	big_int_from_u64(&d, y);
 	big_int_from_u64(&d, y);
 	mp_mul(x, &d, dst);
 	mp_mul(x, &d, dst);
@@ -329,12 +329,12 @@ void big_int_mul_u64(BigInt *dst, BigInt const *x, u64 y) {
 }
 }
 
 
 
 
-void big_int_mul(BigInt *dst, BigInt const *x, BigInt const *y) {
+gb_internal void big_int_mul(BigInt *dst, BigInt const *x, BigInt const *y) {
 	mp_mul(x, y, dst);
 	mp_mul(x, y, dst);
 }
 }
 
 
 
 
-u64 leading_zeros_u64(u64 x) {
+gb_internal u64 leading_zeros_u64(u64 x) {
 #if defined(GB_COMPILER_MSVC)
 #if defined(GB_COMPILER_MSVC)
 	#if defined(GB_ARCH_64_BIT)
 	#if defined(GB_ARCH_64_BIT)
 		return __lzcnt64(x);
 		return __lzcnt64(x);
@@ -367,23 +367,23 @@ u64 leading_zeros_u64(u64 x) {
 //
 //
 // q = x/y with the result truncated to zero
 // q = x/y with the result truncated to zero
 // r = x - y*q
 // r = x - y*q
-void big_int_quo_rem(BigInt const *x, BigInt const *y, BigInt *q_, BigInt *r_) {
+gb_internal void big_int_quo_rem(BigInt const *x, BigInt const *y, BigInt *q_, BigInt *r_) {
 	mp_div(x, y, q_, r_);
 	mp_div(x, y, q_, r_);
 }
 }
 
 
-void big_int_quo(BigInt *z, BigInt const *x, BigInt const *y) {
+gb_internal void big_int_quo(BigInt *z, BigInt const *x, BigInt const *y) {
 	BigInt r = {};
 	BigInt r = {};
 	big_int_quo_rem(x, y, z, &r);
 	big_int_quo_rem(x, y, z, &r);
 	big_int_dealloc(&r);
 	big_int_dealloc(&r);
 }
 }
 
 
-void big_int_rem(BigInt *z, BigInt const *x, BigInt const *y) {
+gb_internal void big_int_rem(BigInt *z, BigInt const *x, BigInt const *y) {
 	BigInt q = {};
 	BigInt q = {};
 	big_int_quo_rem(x, y, &q, z);
 	big_int_quo_rem(x, y, &q, z);
 	big_int_dealloc(&q);
 	big_int_dealloc(&q);
 }
 }
 
 
-void big_int_euclidean_mod(BigInt *z, BigInt const *x, BigInt const *y) {
+gb_internal void big_int_euclidean_mod(BigInt *z, BigInt const *x, BigInt const *y) {
 	BigInt y0 = {};
 	BigInt y0 = {};
 	big_int_init(&y0, y);
 	big_int_init(&y0, y);
 
 
@@ -400,11 +400,11 @@ void big_int_euclidean_mod(BigInt *z, BigInt const *x, BigInt const *y) {
 
 
 
 
 
 
-void big_int_and(BigInt *dst, BigInt const *x, BigInt const *y) {
+gb_internal void big_int_and(BigInt *dst, BigInt const *x, BigInt const *y) {
 	mp_and(x, y, dst);
 	mp_and(x, y, dst);
 }
 }
 
 
-void big_int_and_not(BigInt *dst, BigInt const *x, BigInt const *y) {
+gb_internal void big_int_and_not(BigInt *dst, BigInt const *x, BigInt const *y) {
 	if (mp_iszero(x)) {
 	if (mp_iszero(x)) {
 		big_int_init(dst, y);
 		big_int_init(dst, y);
 		return;
 		return;
@@ -467,22 +467,22 @@ void big_int_and_not(BigInt *dst, BigInt const *x, BigInt const *y) {
 	return;
 	return;
 }
 }
 
 
-void big_int_xor(BigInt *dst, BigInt const *x, BigInt const *y) {
+gb_internal void big_int_xor(BigInt *dst, BigInt const *x, BigInt const *y) {
 	mp_xor(x, y, dst);
 	mp_xor(x, y, dst);
 }
 }
 
 
 
 
-void big_int_or(BigInt *dst, BigInt const *x, BigInt const *y) {
+gb_internal void big_int_or(BigInt *dst, BigInt const *x, BigInt const *y) {
 	mp_or(x, y, dst);
 	mp_or(x, y, dst);
 }
 }
 
 
-void debug_print_big_int(BigInt const *x) {
+gb_internal void debug_print_big_int(BigInt const *x) {
 	String s = big_int_to_string(temporary_allocator(), x, 10);
 	String s = big_int_to_string(temporary_allocator(), x, 10);
 	gb_printf_err("[DEBUG] %.*s\n", LIT(s));
 	gb_printf_err("[DEBUG] %.*s\n", LIT(s));
 }
 }
 
 
 
 
-void big_int_not(BigInt *dst, BigInt const *x, i32 bit_count, bool is_signed) {
+gb_internal void big_int_not(BigInt *dst, BigInt const *x, i32 bit_count, bool is_signed) {
 	GB_ASSERT(bit_count >= 0);
 	GB_ASSERT(bit_count >= 0);
 	if (bit_count == 0) {
 	if (bit_count == 0) {
 		big_int_from_u64(dst, 0);
 		big_int_from_u64(dst, 0);
@@ -530,7 +530,7 @@ void big_int_not(BigInt *dst, BigInt const *x, i32 bit_count, bool is_signed) {
 	big_int_dealloc(&v);
 	big_int_dealloc(&v);
 }
 }
 
 
-bool big_int_is_neg(BigInt const *x) {
+gb_internal bool big_int_is_neg(BigInt const *x) {
 	if (x == nullptr) {
 	if (x == nullptr) {
 		return false;
 		return false;
 	}
 	}
@@ -538,7 +538,7 @@ bool big_int_is_neg(BigInt const *x) {
 }
 }
 
 
 
 
-char digit_to_char(u8 digit) {
+gb_internal char digit_to_char(u8 digit) {
 	GB_ASSERT(digit < 16);
 	GB_ASSERT(digit < 16);
 	if (digit <= 9) {
 	if (digit <= 9) {
 		return digit + '0';
 		return digit + '0';
@@ -548,7 +548,7 @@ char digit_to_char(u8 digit) {
 	return '0';
 	return '0';
 }
 }
 
 
-String big_int_to_string(gbAllocator allocator, BigInt const *x, u64 base) {
+gb_internal String big_int_to_string(gbAllocator allocator, BigInt const *x, u64 base) {
 	GB_ASSERT(base <= 16);
 	GB_ASSERT(base <= 16);
 
 
 	if (mp_iszero(x)) {
 	if (mp_iszero(x)) {

+ 6 - 6
src/bug_report.cpp

@@ -30,7 +30,7 @@
 	NOTE(Jeroen): This prints the Windows product edition only, to be called from `print_platform_details`.
 	NOTE(Jeroen): This prints the Windows product edition only, to be called from `print_platform_details`.
 */
 */
 #if defined(GB_SYSTEM_WINDOWS)
 #if defined(GB_SYSTEM_WINDOWS)
-void report_windows_product_type(DWORD ProductType) {
+gb_internal void report_windows_product_type(DWORD ProductType) {
 	switch (ProductType) {
 	switch (ProductType) {
 	case PRODUCT_ULTIMATE:
 	case PRODUCT_ULTIMATE:
 		gb_printf("Ultimate");
 		gb_printf("Ultimate");
@@ -154,7 +154,7 @@ void report_windows_product_type(DWORD ProductType) {
 }
 }
 #endif
 #endif
 
 
-void odin_cpuid(int leaf, int result[]) {
+gb_internal void odin_cpuid(int leaf, int result[]) {
 	#if defined(GB_CPU_ARM)
 	#if defined(GB_CPU_ARM)
 		return;
 		return;
 
 
@@ -169,7 +169,7 @@ void odin_cpuid(int leaf, int result[]) {
 	#endif
 	#endif
 }
 }
 
 
-void report_cpu_info() {
+gb_internal void report_cpu_info() {
 	gb_printf("\tCPU:  ");
 	gb_printf("\tCPU:  ");
 
 
 	#if defined(GB_CPU_X86)
 	#if defined(GB_CPU_X86)
@@ -220,7 +220,7 @@ void report_cpu_info() {
 /*
 /*
 	Report the amount of installed RAM.
 	Report the amount of installed RAM.
 */
 */
-void report_ram_info() {
+gb_internal void report_ram_info() {
 	gb_printf("\tRAM:  ");
 	gb_printf("\tRAM:  ");
 
 
 	#if defined(GB_SYSTEM_WINDOWS)
 	#if defined(GB_SYSTEM_WINDOWS)
@@ -271,7 +271,7 @@ void report_ram_info() {
 	#endif
 	#endif
 }
 }
 
 
-void report_os_info() {
+gb_internal void report_os_info() {
 	gb_printf("\tOS:   ");
 	gb_printf("\tOS:   ");
 
 
 	#if defined(GB_SYSTEM_WINDOWS)
 	#if defined(GB_SYSTEM_WINDOWS)
@@ -966,7 +966,7 @@ void report_os_info() {
 }
 }
 
 
 // NOTE(Jeroen): `odin report` prints some system information for easier bug reporting.
 // NOTE(Jeroen): `odin report` prints some system information for easier bug reporting.
-void print_bug_report_help() {
+gb_internal void print_bug_report_help() {
 	gb_printf("Where to find more information and get into contact when you encounter a bug:\n\n");
 	gb_printf("Where to find more information and get into contact when you encounter a bug:\n\n");
 	gb_printf("\tWebsite: https://odin-lang.org\n");
 	gb_printf("\tWebsite: https://odin-lang.org\n");
 	gb_printf("\tGitHub:  https://github.com/odin-lang/Odin/issues\n");
 	gb_printf("\tGitHub:  https://github.com/odin-lang/Odin/issues\n");

+ 52 - 53
src/build_settings.cpp

@@ -57,7 +57,7 @@ enum TargetABIKind : u16 {
 };
 };
 
 
 
 
-String target_os_names[TargetOs_COUNT] = {
+gb_global String target_os_names[TargetOs_COUNT] = {
 	str_lit(""),
 	str_lit(""),
 	str_lit("windows"),
 	str_lit("windows"),
 	str_lit("darwin"),
 	str_lit("darwin"),
@@ -72,7 +72,7 @@ String target_os_names[TargetOs_COUNT] = {
 	str_lit("freestanding"),
 	str_lit("freestanding"),
 };
 };
 
 
-String target_arch_names[TargetArch_COUNT] = {
+gb_global String target_arch_names[TargetArch_COUNT] = {
 	str_lit(""),
 	str_lit(""),
 	str_lit("amd64"),
 	str_lit("amd64"),
 	str_lit("i386"),
 	str_lit("i386"),
@@ -82,19 +82,19 @@ String target_arch_names[TargetArch_COUNT] = {
 	str_lit("wasm64"),
 	str_lit("wasm64"),
 };
 };
 
 
-String target_endian_names[TargetEndian_COUNT] = {
+gb_global String target_endian_names[TargetEndian_COUNT] = {
 	str_lit(""),
 	str_lit(""),
 	str_lit("little"),
 	str_lit("little"),
 	str_lit("big"),
 	str_lit("big"),
 };
 };
 
 
-String target_abi_names[TargetABI_COUNT] = {
+gb_global String target_abi_names[TargetABI_COUNT] = {
 	str_lit(""),
 	str_lit(""),
 	str_lit("win64"),
 	str_lit("win64"),
 	str_lit("sysv"),
 	str_lit("sysv"),
 };
 };
 
 
-TargetEndianKind target_endians[TargetArch_COUNT] = {
+gb_global TargetEndianKind target_endians[TargetArch_COUNT] = {
 	TargetEndian_Invalid,
 	TargetEndian_Invalid,
 	TargetEndian_Little,
 	TargetEndian_Little,
 	TargetEndian_Little,
 	TargetEndian_Little,
@@ -107,7 +107,7 @@ TargetEndianKind target_endians[TargetArch_COUNT] = {
 #define ODIN_VERSION_RAW "dev-unknown-unknown"
 #define ODIN_VERSION_RAW "dev-unknown-unknown"
 #endif
 #endif
 
 
-String const ODIN_VERSION = str_lit(ODIN_VERSION_RAW);
+gb_global String const ODIN_VERSION = str_lit(ODIN_VERSION_RAW);
 
 
 
 
 
 
@@ -149,7 +149,6 @@ enum CommandKind : u32 {
 	Command_run             = 1<<0,
 	Command_run             = 1<<0,
 	Command_build           = 1<<1,
 	Command_build           = 1<<1,
 	Command_check           = 1<<3,
 	Command_check           = 1<<3,
-	Command_query           = 1<<4,
 	Command_doc             = 1<<5,
 	Command_doc             = 1<<5,
 	Command_version         = 1<<6,
 	Command_version         = 1<<6,
 	Command_test            = 1<<7,
 	Command_test            = 1<<7,
@@ -157,16 +156,15 @@ enum CommandKind : u32 {
 	Command_strip_semicolon = 1<<8,
 	Command_strip_semicolon = 1<<8,
 	Command_bug_report      = 1<<9,
 	Command_bug_report      = 1<<9,
 
 
-	Command__does_check = Command_run|Command_build|Command_check|Command_query|Command_doc|Command_test|Command_strip_semicolon,
+	Command__does_check = Command_run|Command_build|Command_check|Command_doc|Command_test|Command_strip_semicolon,
 	Command__does_build = Command_run|Command_build|Command_test,
 	Command__does_build = Command_run|Command_build|Command_test,
 	Command_all = ~(u32)0,
 	Command_all = ~(u32)0,
 };
 };
 
 
-char const *odin_command_strings[32] = {
+gb_global char const *odin_command_strings[32] = {
 	"run",
 	"run",
 	"build",
 	"build",
 	"check",
 	"check",
-	"query",
 	"doc",
 	"doc",
 	"version",
 	"version",
 	"test",
 	"test",
@@ -316,8 +314,6 @@ struct BuildContext {
 	u32 cmd_doc_flags;
 	u32 cmd_doc_flags;
 	Array<String> extra_packages;
 	Array<String> extra_packages;
 
 
-	QueryDataSetSettings query_data_set_settings;
-
 	StringSet test_names;
 	StringSet test_names;
 
 
 	gbAffinity affinity;
 	gbAffinity affinity;
@@ -333,10 +329,10 @@ struct BuildContext {
 
 
 gb_global BuildContext build_context = {0};
 gb_global BuildContext build_context = {0};
 
 
-bool global_warnings_as_errors(void) {
+gb_internal bool global_warnings_as_errors(void) {
 	return build_context.warnings_as_errors;
 	return build_context.warnings_as_errors;
 }
 }
-bool global_ignore_warnings(void) {
+gb_internal bool global_ignore_warnings(void) {
 	return build_context.ignore_warnings;
 	return build_context.ignore_warnings;
 }
 }
 
 
@@ -398,7 +394,7 @@ gb_global TargetMetrics target_darwin_arm64 = {
 	TargetArch_arm64,
 	TargetArch_arm64,
 	8, 8, 16,
 	8, 8, 16,
 	str_lit("arm64-apple-macosx11.0.0"),
 	str_lit("arm64-apple-macosx11.0.0"),
-	str_lit("e-m:o-i64:64-i128:128-n32:64-S128"), // TODO(bill): Is this correct?
+	str_lit("e-m:o-i64:64-i128:128-n32:64-S128"),
 };
 };
 
 
 gb_global TargetMetrics target_freebsd_i386 = {
 gb_global TargetMetrics target_freebsd_i386 = {
@@ -502,9 +498,9 @@ gb_global NamedTargetMetrics named_targets[] = {
 	{ str_lit("freestanding_amd64_sysv"), &target_freestanding_amd64_sysv },
 	{ str_lit("freestanding_amd64_sysv"), &target_freestanding_amd64_sysv },
 };
 };
 
 
-NamedTargetMetrics *selected_target_metrics;
+gb_global NamedTargetMetrics *selected_target_metrics;
 
 
-TargetOsKind get_target_os_from_string(String str) {
+gb_internal TargetOsKind get_target_os_from_string(String str) {
 	for (isize i = 0; i < TargetOs_COUNT; i++) {
 	for (isize i = 0; i < TargetOs_COUNT; i++) {
 		if (str_eq_ignore_case(target_os_names[i], str)) {
 		if (str_eq_ignore_case(target_os_names[i], str)) {
 			return cast(TargetOsKind)i;
 			return cast(TargetOsKind)i;
@@ -513,7 +509,7 @@ TargetOsKind get_target_os_from_string(String str) {
 	return TargetOs_Invalid;
 	return TargetOs_Invalid;
 }
 }
 
 
-TargetArchKind get_target_arch_from_string(String str) {
+gb_internal TargetArchKind get_target_arch_from_string(String str) {
 	for (isize i = 0; i < TargetArch_COUNT; i++) {
 	for (isize i = 0; i < TargetArch_COUNT; i++) {
 		if (str_eq_ignore_case(target_arch_names[i], str)) {
 		if (str_eq_ignore_case(target_arch_names[i], str)) {
 			return cast(TargetArchKind)i;
 			return cast(TargetArchKind)i;
@@ -523,7 +519,7 @@ TargetArchKind get_target_arch_from_string(String str) {
 }
 }
 
 
 
 
-bool is_excluded_target_filename(String name) {
+gb_internal bool is_excluded_target_filename(String name) {
 	String original_name = name;
 	String original_name = name;
 	name = remove_extension_from_path(name);
 	name = remove_extension_from_path(name);
 
 
@@ -588,13 +584,12 @@ struct LibraryCollections {
 
 
 gb_global Array<LibraryCollections> library_collections = {0};
 gb_global Array<LibraryCollections> library_collections = {0};
 
 
-void add_library_collection(String name, String path) {
-	// TODO(bill): Check the path is valid and a directory
+gb_internal void add_library_collection(String name, String path) {
 	LibraryCollections lc = {name, string_trim_whitespace(path)};
 	LibraryCollections lc = {name, string_trim_whitespace(path)};
 	array_add(&library_collections, lc);
 	array_add(&library_collections, lc);
 }
 }
 
 
-bool find_library_collection_path(String name, String *path) {
+gb_internal bool find_library_collection_path(String name, String *path) {
 	for_array(i, library_collections) {
 	for_array(i, library_collections) {
 		if (library_collections[i].name == name) {
 		if (library_collections[i].name == name) {
 			if (path) *path = library_collections[i].path;
 			if (path) *path = library_collections[i].path;
@@ -604,7 +599,7 @@ bool find_library_collection_path(String name, String *path) {
 	return false;
 	return false;
 }
 }
 
 
-bool is_arch_wasm(void) {
+gb_internal bool is_arch_wasm(void) {
 	switch (build_context.metrics.arch) {
 	switch (build_context.metrics.arch) {
 	case TargetArch_wasm32:
 	case TargetArch_wasm32:
 	case TargetArch_wasm64:
 	case TargetArch_wasm64:
@@ -613,7 +608,7 @@ bool is_arch_wasm(void) {
 	return false;
 	return false;
 }
 }
 
 
-bool is_arch_x86(void) {
+gb_internal bool is_arch_x86(void) {
 	switch (build_context.metrics.arch) {
 	switch (build_context.metrics.arch) {
 	case TargetArch_i386:
 	case TargetArch_i386:
 	case TargetArch_amd64:
 	case TargetArch_amd64:
@@ -622,7 +617,7 @@ bool is_arch_x86(void) {
 	return false;
 	return false;
 }
 }
 
 
-bool allow_check_foreign_filepath(void) {
+gb_internal bool allow_check_foreign_filepath(void) {
 	switch (build_context.metrics.arch) {
 	switch (build_context.metrics.arch) {
 	case TargetArch_wasm32:
 	case TargetArch_wasm32:
 	case TargetArch_wasm64:
 	case TargetArch_wasm64:
@@ -638,13 +633,14 @@ bool allow_check_foreign_filepath(void) {
 // is_abs_path
 // is_abs_path
 // has_subdir
 // has_subdir
 
 
-String const WIN32_SEPARATOR_STRING = {cast(u8 *)"\\", 1};
-String const NIX_SEPARATOR_STRING   = {cast(u8 *)"/",  1};
+gb_global String const WIN32_SEPARATOR_STRING = {cast(u8 *)"\\", 1};
+gb_global String const NIX_SEPARATOR_STRING   = {cast(u8 *)"/",  1};
+
+gb_global String const WASM_MODULE_NAME_SEPARATOR = str_lit("..");
 
 
-String const WASM_MODULE_NAME_SEPARATOR = str_lit("..");
+gb_internal String internal_odin_root_dir(void);
 
 
-String internal_odin_root_dir(void);
-String odin_root_dir(void) {
+gb_internal String odin_root_dir(void) {
 	if (global_module_path_set) {
 	if (global_module_path_set) {
 		return global_module_path;
 		return global_module_path;
 	}
 	}
@@ -670,7 +666,7 @@ String odin_root_dir(void) {
 
 
 
 
 #if defined(GB_SYSTEM_WINDOWS)
 #if defined(GB_SYSTEM_WINDOWS)
-String internal_odin_root_dir(void) {
+gb_internal String internal_odin_root_dir(void) {
 	String path = global_module_path;
 	String path = global_module_path;
 	isize len, i;
 	isize len, i;
 	wchar_t *text;
 	wchar_t *text;
@@ -723,9 +719,9 @@ String internal_odin_root_dir(void) {
 
 
 #include <mach-o/dyld.h>
 #include <mach-o/dyld.h>
 
 
-String path_to_fullpath(gbAllocator a, String s);
+gb_internal String path_to_fullpath(gbAllocator a, String s);
 
 
-String internal_odin_root_dir(void) {
+gb_internal String internal_odin_root_dir(void) {
 	String path = global_module_path;
 	String path = global_module_path;
 	isize len, i;
 	isize len, i;
 	u8 *text;
 	u8 *text;
@@ -777,9 +773,9 @@ String internal_odin_root_dir(void) {
 // NOTE: Linux / Unix is unfinished and not tested very well.
 // NOTE: Linux / Unix is unfinished and not tested very well.
 #include <sys/stat.h>
 #include <sys/stat.h>
 
 
-String path_to_fullpath(gbAllocator a, String s);
+gb_internal String path_to_fullpath(gbAllocator a, String s);
 
 
-String internal_odin_root_dir(void) {
+gb_internal String internal_odin_root_dir(void) {
 	String path = global_module_path;
 	String path = global_module_path;
 	isize len, i;
 	isize len, i;
 	u8 *text;
 	u8 *text;
@@ -938,7 +934,7 @@ String internal_odin_root_dir(void) {
 gb_global BlockingMutex fullpath_mutex;
 gb_global BlockingMutex fullpath_mutex;
 
 
 #if defined(GB_SYSTEM_WINDOWS)
 #if defined(GB_SYSTEM_WINDOWS)
-String path_to_fullpath(gbAllocator a, String s) {
+gb_internal String path_to_fullpath(gbAllocator a, String s) {
 	String result = {};
 	String result = {};
 	mutex_lock(&fullpath_mutex);
 	mutex_lock(&fullpath_mutex);
 	defer (mutex_unlock(&fullpath_mutex));
 	defer (mutex_unlock(&fullpath_mutex));
@@ -965,7 +961,7 @@ String path_to_fullpath(gbAllocator a, String s) {
 	return result;
 	return result;
 }
 }
 #elif defined(GB_SYSTEM_OSX) || defined(GB_SYSTEM_UNIX)
 #elif defined(GB_SYSTEM_OSX) || defined(GB_SYSTEM_UNIX)
-String path_to_fullpath(gbAllocator a, String s) {
+gb_internal String path_to_fullpath(gbAllocator a, String s) {
 	char *p;
 	char *p;
 	mutex_lock(&fullpath_mutex);
 	mutex_lock(&fullpath_mutex);
 	p = realpath(cast(char *)s.text, 0);
 	p = realpath(cast(char *)s.text, 0);
@@ -978,7 +974,7 @@ String path_to_fullpath(gbAllocator a, String s) {
 #endif
 #endif
 
 
 
 
-String get_fullpath_relative(gbAllocator a, String base_dir, String path) {
+gb_internal String get_fullpath_relative(gbAllocator a, String base_dir, String path) {
 	u8 *str = gb_alloc_array(heap_allocator(), u8, base_dir.len+1+path.len+1);
 	u8 *str = gb_alloc_array(heap_allocator(), u8, base_dir.len+1+path.len+1);
 	defer (gb_free(heap_allocator(), str));
 	defer (gb_free(heap_allocator(), str));
 
 
@@ -1004,7 +1000,7 @@ String get_fullpath_relative(gbAllocator a, String base_dir, String path) {
 }
 }
 
 
 
 
-String get_fullpath_core(gbAllocator a, String path) {
+gb_internal String get_fullpath_core(gbAllocator a, String path) {
 	String module_dir = odin_root_dir();
 	String module_dir = odin_root_dir();
 
 
 	String core = str_lit("core/");
 	String core = str_lit("core/");
@@ -1024,11 +1020,11 @@ String get_fullpath_core(gbAllocator a, String path) {
 	return path_to_fullpath(a, res);
 	return path_to_fullpath(a, res);
 }
 }
 
 
-bool show_error_line(void) {
+gb_internal bool show_error_line(void) {
 	return build_context.show_error_line;
 	return build_context.show_error_line;
 }
 }
 
 
-bool has_asm_extension(String const &path) {
+gb_internal bool has_asm_extension(String const &path) {
 	String ext = path_extension(path);
 	String ext = path_extension(path);
 	if (ext == ".asm") {
 	if (ext == ".asm") {
 		return true;
 		return true;
@@ -1041,7 +1037,7 @@ bool has_asm_extension(String const &path) {
 }
 }
 
 
 // temporary
 // temporary
-char *token_pos_to_string(TokenPos const &pos) {
+gb_internal char *token_pos_to_string(TokenPos const &pos) {
 	gbString s = gb_string_make_reserve(temporary_allocator(), 128);
 	gbString s = gb_string_make_reserve(temporary_allocator(), 128);
 	String file = get_file_path_string(pos.file_id);
 	String file = get_file_path_string(pos.file_id);
 	switch (build_context.ODIN_ERROR_POS_STYLE) {
 	switch (build_context.ODIN_ERROR_POS_STYLE) {
@@ -1056,7 +1052,7 @@ char *token_pos_to_string(TokenPos const &pos) {
 	return s;
 	return s;
 }
 }
 
 
-void init_build_context(TargetMetrics *cross_target) {
+gb_internal void init_build_context(TargetMetrics *cross_target) {
 	BuildContext *bc = &build_context;
 	BuildContext *bc = &build_context;
 
 
 	gb_affinity_init(&bc->affinity);
 	gb_affinity_init(&bc->affinity);
@@ -1258,7 +1254,7 @@ void init_build_context(TargetMetrics *cross_target) {
 #endif
 #endif
 
 
 
 
-Array<String> split_by_comma(String const &list) {
+gb_internal Array<String> split_by_comma(String const &list) {
 	isize n = 1;
 	isize n = 1;
 	for (isize i = 0; i < list.len; i++) {
 	for (isize i = 0; i < list.len; i++) {
 		if (list.text[i] == ',') {
 		if (list.text[i] == ',') {
@@ -1280,12 +1276,12 @@ Array<String> split_by_comma(String const &list) {
 	return res;
 	return res;
 }
 }
 
 
-bool check_target_feature_is_valid(TokenPos pos, String const &feature) {
+gb_internal bool check_target_feature_is_valid(TokenPos pos, String const &feature) {
 	// TODO(bill): check_target_feature_is_valid
 	// TODO(bill): check_target_feature_is_valid
 	return true;
 	return true;
 }
 }
 
 
-bool check_target_feature_is_enabled(TokenPos pos, String const &target_feature_list) {
+gb_internal bool check_target_feature_is_enabled(TokenPos pos, String const &target_feature_list) {
 	BuildContext *bc = &build_context;
 	BuildContext *bc = &build_context;
 	mutex_lock(&bc->target_features_mutex);
 	mutex_lock(&bc->target_features_mutex);
 	defer (mutex_unlock(&bc->target_features_mutex));
 	defer (mutex_unlock(&bc->target_features_mutex));
@@ -1307,7 +1303,7 @@ bool check_target_feature_is_enabled(TokenPos pos, String const &target_feature_
 	return true;
 	return true;
 }
 }
 
 
-void enable_target_feature(TokenPos pos, String const &target_feature_list) {
+gb_internal void enable_target_feature(TokenPos pos, String const &target_feature_list) {
 	BuildContext *bc = &build_context;
 	BuildContext *bc = &build_context;
 	mutex_lock(&bc->target_features_mutex);
 	mutex_lock(&bc->target_features_mutex);
 	defer (mutex_unlock(&bc->target_features_mutex));
 	defer (mutex_unlock(&bc->target_features_mutex));
@@ -1326,25 +1322,28 @@ void enable_target_feature(TokenPos pos, String const &target_feature_list) {
 }
 }
 
 
 
 
-char const *target_features_set_to_cstring(gbAllocator allocator, bool with_quotes) {
+gb_internal 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++] = '"';
@@ -1356,7 +1355,7 @@ char const *target_features_set_to_cstring(gbAllocator allocator, bool with_quot
 
 
 // NOTE(Jeroen): Set/create the output and other paths and report an error as appropriate.
 // NOTE(Jeroen): Set/create the output and other paths and report an error as appropriate.
 // We've previously called `parse_build_flags`, so `out_filepath` should be set.
 // We've previously called `parse_build_flags`, so `out_filepath` should be set.
-bool init_build_paths(String init_filename) {
+gb_internal bool init_build_paths(String init_filename) {
 	gbAllocator   ha = heap_allocator();
 	gbAllocator   ha = heap_allocator();
 	BuildContext *bc = &build_context;
 	BuildContext *bc = &build_context;
 
 

+ 22 - 28
src/check_builtin.cpp

@@ -1,6 +1,6 @@
 typedef bool (BuiltinTypeIsProc)(Type *t);
 typedef bool (BuiltinTypeIsProc)(Type *t);
 
 
-BuiltinTypeIsProc *builtin_type_is_procs[BuiltinProc__type_simple_boolean_end - BuiltinProc__type_simple_boolean_begin] = {
+gb_global BuiltinTypeIsProc *builtin_type_is_procs[BuiltinProc__type_simple_boolean_end - BuiltinProc__type_simple_boolean_begin] = {
 	nullptr, // BuiltinProc__type_simple_boolean_begin
 	nullptr, // BuiltinProc__type_simple_boolean_begin
 
 
 	is_type_boolean,
 	is_type_boolean,
@@ -51,7 +51,7 @@ BuiltinTypeIsProc *builtin_type_is_procs[BuiltinProc__type_simple_boolean_end -
 };
 };
 
 
 
 
-void check_or_else_right_type(CheckerContext *c, Ast *expr, String const &name, Type *right_type) {
+gb_internal void check_or_else_right_type(CheckerContext *c, Ast *expr, String const &name, Type *right_type) {
 	if (right_type == nullptr) {
 	if (right_type == nullptr) {
 		return;
 		return;
 	}
 	}
@@ -62,7 +62,7 @@ void check_or_else_right_type(CheckerContext *c, Ast *expr, String const &name,
 	}
 	}
 }
 }
 
 
-void check_or_else_split_types(CheckerContext *c, Operand *x, String const &name, Type **left_type_, Type **right_type_) {
+gb_internal void check_or_else_split_types(CheckerContext *c, Operand *x, String const &name, Type **left_type_, Type **right_type_) {
 	Type *left_type = nullptr;
 	Type *left_type = nullptr;
 	Type *right_type = nullptr;
 	Type *right_type = nullptr;
 	if (x->type->kind == Type_Tuple) {
 	if (x->type->kind == Type_Tuple) {
@@ -88,8 +88,7 @@ void check_or_else_split_types(CheckerContext *c, Operand *x, String const &name
 }
 }
 
 
 
 
-void check_or_else_expr_no_value_error(CheckerContext *c, String const &name, Operand const &x, Type *type_hint) {
-	// TODO(bill): better error message
+gb_internal void check_or_else_expr_no_value_error(CheckerContext *c, String const &name, Operand const &x, Type *type_hint) {
 	gbString t = type_to_string(x.type);
 	gbString t = type_to_string(x.type);
 	error(x.expr, "'%.*s' does not return a value, value is of type %s", LIT(name), t);
 	error(x.expr, "'%.*s' does not return a value, value is of type %s", LIT(name), t);
 	if (is_type_union(type_deref(x.type))) {
 	if (is_type_union(type_deref(x.type))) {
@@ -118,7 +117,7 @@ void check_or_else_expr_no_value_error(CheckerContext *c, String const &name, Op
 }
 }
 
 
 
 
-void check_or_return_split_types(CheckerContext *c, Operand *x, String const &name, Type **left_type_, Type **right_type_) {
+gb_internal void check_or_return_split_types(CheckerContext *c, Operand *x, String const &name, Type **left_type_, Type **right_type_) {
 	Type *left_type = nullptr;
 	Type *left_type = nullptr;
 	Type *right_type = nullptr;
 	Type *right_type = nullptr;
 	if (x->type->kind == Type_Tuple) {
 	if (x->type->kind == Type_Tuple) {
@@ -144,7 +143,7 @@ void check_or_return_split_types(CheckerContext *c, Operand *x, String const &na
 }
 }
 
 
 
 
-bool does_require_msgSend_stret(Type *return_type) {
+gb_internal bool does_require_msgSend_stret(Type *return_type) {
 	if (return_type == nullptr) {
 	if (return_type == nullptr) {
 		return false;
 		return false;
 	}
 	}
@@ -165,7 +164,7 @@ bool does_require_msgSend_stret(Type *return_type) {
 	return false;
 	return false;
 }
 }
 
 
-ObjcMsgKind get_objc_proc_kind(Type *return_type) {
+gb_internal ObjcMsgKind get_objc_proc_kind(Type *return_type) {
 	if (return_type == nullptr) {
 	if (return_type == nullptr) {
 		return ObjcMsg_normal;
 		return ObjcMsg_normal;
 	}
 	}
@@ -189,7 +188,7 @@ ObjcMsgKind get_objc_proc_kind(Type *return_type) {
 	return ObjcMsg_normal;
 	return ObjcMsg_normal;
 }
 }
 
 
-void add_objc_proc_type(CheckerContext *c, Ast *call, Type *return_type, Slice<Type *> param_types) {
+gb_internal void add_objc_proc_type(CheckerContext *c, Ast *call, Type *return_type, Slice<Type *> param_types) {
 	ObjcMsgKind kind = get_objc_proc_kind(return_type);
 	ObjcMsgKind kind = get_objc_proc_kind(return_type);
 
 
 	Scope *scope = create_scope(c->info, nullptr);
 	Scope *scope = create_scope(c->info, nullptr);
@@ -230,7 +229,7 @@ void add_objc_proc_type(CheckerContext *c, Ast *call, Type *return_type, Slice<T
 	try_to_add_package_dependency(c, "runtime", "objc_msgSend_stret");
 	try_to_add_package_dependency(c, "runtime", "objc_msgSend_stret");
 }
 }
 
 
-bool is_constant_string(CheckerContext *c, String const &builtin_name, Ast *expr, String *name_) {
+gb_internal bool is_constant_string(CheckerContext *c, String const &builtin_name, Ast *expr, String *name_) {
 	Operand op = {};
 	Operand op = {};
 	check_expr(c, &op, expr);
 	check_expr(c, &op, expr);
 	if (op.mode == Addressing_Constant && op.value.kind == ExactValue_String) {
 	if (op.mode == Addressing_Constant && op.value.kind == ExactValue_String) {
@@ -245,7 +244,7 @@ bool is_constant_string(CheckerContext *c, String const &builtin_name, Ast *expr
 	return false;
 	return false;
 }
 }
 
 
-bool check_builtin_objc_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 id, Type *type_hint) {
+gb_internal bool check_builtin_objc_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 id, Type *type_hint) {
 	String const &builtin_name = builtin_procs[id].name;
 	String const &builtin_name = builtin_procs[id].name;
 
 
 	if (build_context.metrics.os != TargetOs_darwin) {
 	if (build_context.metrics.os != TargetOs_darwin) {
@@ -387,7 +386,7 @@ bool check_builtin_objc_procedure(CheckerContext *c, Operand *operand, Ast *call
 	}
 	}
 }
 }
 
 
-bool check_atomic_memory_order_argument(CheckerContext *c, Ast *expr, String const &builtin_name, OdinAtomicMemoryOrder *memory_order_, char const *extra_message = nullptr) {
+gb_internal bool check_atomic_memory_order_argument(CheckerContext *c, Ast *expr, String const &builtin_name, OdinAtomicMemoryOrder *memory_order_, char const *extra_message = nullptr) {
 	Operand x = {};
 	Operand x = {};
 	check_expr_with_type_hint(c, &x, expr, t_atomic_memory_order);
 	check_expr_with_type_hint(c, &x, expr, t_atomic_memory_order);
 	if (x.mode == Addressing_Invalid) {
 	if (x.mode == Addressing_Invalid) {
@@ -417,7 +416,7 @@ bool check_atomic_memory_order_argument(CheckerContext *c, Ast *expr, String con
 }
 }
 
 
 
 
-bool check_builtin_simd_operation(CheckerContext *c, Operand *operand, Ast *call, i32 id, Type *type_hint) {
+gb_internal bool check_builtin_simd_operation(CheckerContext *c, Operand *operand, Ast *call, i32 id, Type *type_hint) {
 	ast_node(ce, CallExpr, call);
 	ast_node(ce, CallExpr, call);
 
 
 	String const &builtin_name = builtin_procs[id].name;
 	String const &builtin_name = builtin_procs[id].name;
@@ -1081,7 +1080,7 @@ bool check_builtin_simd_operation(CheckerContext *c, Operand *operand, Ast *call
 	return false;
 	return false;
 }
 }
 
 
-bool cache_load_file_directive(CheckerContext *c, Ast *call, String const &original_string, bool err_on_not_found, LoadFileCache **cache_) {
+gb_internal bool cache_load_file_directive(CheckerContext *c, Ast *call, String const &original_string, bool err_on_not_found, LoadFileCache **cache_) {
 	ast_node(ce, CallExpr, call);
 	ast_node(ce, CallExpr, call);
 	ast_node(bd, BasicDirective, ce->proc);
 	ast_node(bd, BasicDirective, ce->proc);
 	String builtin_name = bd->name.string;
 	String builtin_name = bd->name.string;
@@ -1170,7 +1169,7 @@ bool cache_load_file_directive(CheckerContext *c, Ast *call, String const &origi
 }
 }
 
 
 
 
-bool is_valid_type_for_load(Type *type) {
+gb_internal bool is_valid_type_for_load(Type *type) {
 	if (type == t_invalid) {
 	if (type == t_invalid) {
 		return false;
 		return false;
 	} else if (is_type_string(type)) {
 	} else if (is_type_string(type)) {
@@ -1191,7 +1190,7 @@ bool is_valid_type_for_load(Type *type) {
 	return false;
 	return false;
 }
 }
 
 
-LoadDirectiveResult check_load_directive(CheckerContext *c, Operand *operand, Ast *call, Type *type_hint, bool err_on_not_found) {
+gb_internal LoadDirectiveResult check_load_directive(CheckerContext *c, Operand *operand, Ast *call, Type *type_hint, bool err_on_not_found) {
 	ast_node(ce, CallExpr, call);
 	ast_node(ce, CallExpr, call);
 	ast_node(bd, BasicDirective, ce->proc);
 	ast_node(bd, BasicDirective, ce->proc);
 	String name = bd->name.string;
 	String name = bd->name.string;
@@ -1256,7 +1255,7 @@ LoadDirectiveResult check_load_directive(CheckerContext *c, Operand *operand, As
 }
 }
 
 
 
 
-bool check_builtin_procedure_directive(CheckerContext *c, Operand *operand, Ast *call, Type *type_hint) {
+gb_internal bool check_builtin_procedure_directive(CheckerContext *c, Operand *operand, Ast *call, Type *type_hint) {
 	ast_node(ce, CallExpr, call);
 	ast_node(ce, CallExpr, call);
 	ast_node(bd, BasicDirective, ce->proc);
 	ast_node(bd, BasicDirective, ce->proc);
 	String name = bd->name.string;
 	String name = bd->name.string;
@@ -1581,7 +1580,7 @@ bool check_builtin_procedure_directive(CheckerContext *c, Operand *operand, Ast
 	return true;
 	return true;
 }
 }
 
 
-bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 id, Type *type_hint) {
+gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 id, Type *type_hint) {
 	ast_node(ce, CallExpr, call);
 	ast_node(ce, CallExpr, call);
 	if (ce->inlining != ProcInlining_none) {
 	if (ce->inlining != ProcInlining_none) {
 		error(call, "Inlining operators are not allowed on built-in procedures");
 		error(call, "Inlining operators are not allowed on built-in procedures");
@@ -2559,7 +2558,7 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
 		if (is_type_struct(type)) {
 		if (is_type_struct(type)) {
 			isize variable_count = type->Struct.fields.count;
 			isize variable_count = type->Struct.fields.count;
 			slice_init(&tuple->Tuple.variables, a, variable_count);
 			slice_init(&tuple->Tuple.variables, a, variable_count);
-			// TODO(bill): Should I copy each of the entities or is this good enough?
+			// NOTE(bill): don't copy the entities, this should be good enough
 			gb_memmove_array(tuple->Tuple.variables.data, type->Struct.fields.data, variable_count);
 			gb_memmove_array(tuple->Tuple.variables.data, type->Struct.fields.data, variable_count);
 		} else if (is_type_array(type)) {
 		} else if (is_type_array(type)) {
 			isize variable_count = cast(isize)type->Array.count;
 			isize variable_count = cast(isize)type->Array.count;
@@ -3126,13 +3125,11 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
 			}
 			}
 
 
 
 
-			if (string_set_exists(&name_set, name)) {
+			if (string_set_update(&name_set, name)) {
 				error(op.expr, "Field argument name '%.*s' already exists", LIT(name));
 				error(op.expr, "Field argument name '%.*s' already exists", LIT(name));
 			} else {
 			} else {
 				array_add(&types, arg_type->Slice.elem);
 				array_add(&types, arg_type->Slice.elem);
 				array_add(&names, name);
 				array_add(&names, name);
-
-				string_set_add(&name_set, name);
 			}
 			}
 		}
 		}
 
 
@@ -3455,9 +3452,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;
@@ -3769,9 +3765,7 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
 				mp_err err = mp_pack(rop, max_count, &written, MP_LSB_FIRST, size, endian, nails, &x.value.value_integer);
 				mp_err err = mp_pack(rop, max_count, &written, MP_LSB_FIRST, size, endian, nails, &x.value.value_integer);
 				GB_ASSERT(err == MP_OKAY);
 				GB_ASSERT(err == MP_OKAY);
 
 
-				if (id == BuiltinProc_reverse_bits) {
-					// TODO(bill): Should this even be allowed at compile time?
-				} else {
+				if (id != BuiltinProc_reverse_bits) {
 					u64 v = 0;
 					u64 v = 0;
 					switch (id) {
 					switch (id) {
 					case BuiltinProc_count_ones:
 					case BuiltinProc_count_ones:

+ 27 - 45
src/check_decl.cpp

@@ -1,7 +1,7 @@
-void check_stmt          (CheckerContext *ctx, Ast *node, u32 flags);
+gb_internal void check_stmt(CheckerContext *ctx, Ast *node, u32 flags);
 
 
 // NOTE(bill): 'content_name' is for debugging and error messages
 // NOTE(bill): 'content_name' is for debugging and error messages
-Type *check_init_variable(CheckerContext *ctx, Entity *e, Operand *operand, String context_name) {
+gb_internal Type *check_init_variable(CheckerContext *ctx, Entity *e, Operand *operand, String context_name) {
 	if (operand->mode == Addressing_Invalid ||
 	if (operand->mode == Addressing_Invalid ||
 		operand->type == t_invalid ||
 		operand->type == t_invalid ||
 		e->type == t_invalid) {
 		e->type == t_invalid) {
@@ -10,7 +10,6 @@ Type *check_init_variable(CheckerContext *ctx, Entity *e, Operand *operand, Stri
 			gbString expr_str = expr_to_string(operand->expr);
 			gbString expr_str = expr_to_string(operand->expr);
 
 
 			// TODO(bill): is this a good enough error message?
 			// TODO(bill): is this a good enough error message?
-			// TODO(bill): Actually allow built in procedures to be passed around and thus be created on use
 			error(operand->expr,
 			error(operand->expr,
 				  "Cannot assign built-in procedure '%s' in %.*s",
 				  "Cannot assign built-in procedure '%s' in %.*s",
 				  expr_str,
 				  expr_str,
@@ -110,7 +109,7 @@ Type *check_init_variable(CheckerContext *ctx, Entity *e, Operand *operand, Stri
 	return e->type;
 	return e->type;
 }
 }
 
 
-void check_init_variables(CheckerContext *ctx, Entity **lhs, isize lhs_count, Slice<Ast *> const &inits, String context_name) {
+gb_internal void check_init_variables(CheckerContext *ctx, Entity **lhs, isize lhs_count, Slice<Ast *> const &inits, String context_name) {
 	if ((lhs == nullptr || lhs_count == 0) && inits.count == 0) {
 	if ((lhs == nullptr || lhs_count == 0) && inits.count == 0) {
 		return;
 		return;
 	}
 	}
@@ -122,13 +121,6 @@ void check_init_variables(CheckerContext *ctx, Entity **lhs, isize lhs_count, Sl
 	check_unpack_arguments(ctx, lhs, lhs_count, &operands, inits, true, false);
 	check_unpack_arguments(ctx, lhs, lhs_count, &operands, inits, true, false);
 
 
 	isize rhs_count = operands.count;
 	isize rhs_count = operands.count;
-	for_array(i, operands) {
-		if (operands[i].mode == Addressing_Invalid) {
-			// TODO(bill): Should I ignore invalid parameters?
-			// rhs_count--;
-		}
-	}
-
 	isize max = gb_min(lhs_count, rhs_count);
 	isize max = gb_min(lhs_count, rhs_count);
 	for (isize i = 0; i < max; i++) {
 	for (isize i = 0; i < max; i++) {
 		Entity *e = lhs[i];
 		Entity *e = lhs[i];
@@ -144,7 +136,7 @@ void check_init_variables(CheckerContext *ctx, Entity **lhs, isize lhs_count, Sl
 	}
 	}
 }
 }
 
 
-void check_init_constant(CheckerContext *ctx, Entity *e, Operand *operand) {
+gb_internal void check_init_constant(CheckerContext *ctx, Entity *e, Operand *operand) {
 	if (operand->mode == Addressing_Invalid ||
 	if (operand->mode == Addressing_Invalid ||
 		operand->type == t_invalid ||
 		operand->type == t_invalid ||
 		e->type == t_invalid) {
 		e->type == t_invalid) {
@@ -184,7 +176,7 @@ void check_init_constant(CheckerContext *ctx, Entity *e, Operand *operand) {
 }
 }
 
 
 
 
-bool is_type_distinct(Ast *node) {
+gb_internal bool is_type_distinct(Ast *node) {
 	for (;;) {
 	for (;;) {
 		if (node == nullptr) {
 		if (node == nullptr) {
 			return false;
 			return false;
@@ -217,7 +209,7 @@ bool is_type_distinct(Ast *node) {
 	return false;
 	return false;
 }
 }
 
 
-Ast *remove_type_alias_clutter(Ast *node) {
+gb_internal Ast *remove_type_alias_clutter(Ast *node) {
 	for (;;) {
 	for (;;) {
 		if (node == nullptr) {
 		if (node == nullptr) {
 			return nullptr;
 			return nullptr;
@@ -232,17 +224,7 @@ Ast *remove_type_alias_clutter(Ast *node) {
 	}
 	}
 }
 }
 
 
-isize total_attribute_count(DeclInfo *decl) {
-	isize attribute_count = 0;
-	for_array(i, decl->attributes) {
-		Ast *attr = decl->attributes[i];
-		if (attr->kind != Ast_Attribute) continue;
-		attribute_count += attr->Attribute.elems.count;
-	}
-	return attribute_count;
-}
-
-Type *clone_enum_type(CheckerContext *ctx, Type *original_enum_type, Type *named_type) {
+gb_internal Type *clone_enum_type(CheckerContext *ctx, Type *original_enum_type, Type *named_type) {
 	// NOTE(bill, 2022-02-05): Stupid edge case for `distinct` declarations
 	// NOTE(bill, 2022-02-05): Stupid edge case for `distinct` declarations
 	//
 	//
 	//         X :: enum {A, B, C}
 	//         X :: enum {A, B, C}
@@ -288,7 +270,7 @@ Type *clone_enum_type(CheckerContext *ctx, Type *original_enum_type, Type *named
 	return et;
 	return et;
 }
 }
 
 
-void check_type_decl(CheckerContext *ctx, Entity *e, Ast *init_expr, Type *def) {
+gb_internal void check_type_decl(CheckerContext *ctx, Entity *e, Ast *init_expr, Type *def) {
 	GB_ASSERT(e->type == nullptr);
 	GB_ASSERT(e->type == nullptr);
 
 
 	DeclInfo *decl = decl_info_of_entity(e);
 	DeclInfo *decl = decl_info_of_entity(e);
@@ -390,7 +372,7 @@ void check_type_decl(CheckerContext *ctx, Entity *e, Ast *init_expr, Type *def)
 }
 }
 
 
 
 
-void override_entity_in_scope(Entity *original_entity, Entity *new_entity) {
+gb_internal void override_entity_in_scope(Entity *original_entity, Entity *new_entity) {
 	// NOTE(bill): The original_entity's scope may not be same scope that it was inserted into
 	// NOTE(bill): The original_entity's scope may not be same scope that it was inserted into
 	// e.g. file entity inserted into its package scope
 	// e.g. file entity inserted into its package scope
 	String original_name = original_entity->token.string;
 	String original_name = original_entity->token.string;
@@ -433,7 +415,7 @@ void override_entity_in_scope(Entity *original_entity, Entity *new_entity) {
 
 
 
 
 
 
-void check_const_decl(CheckerContext *ctx, Entity *e, Ast *type_expr, Ast *init, Type *named_type) {
+gb_internal void check_const_decl(CheckerContext *ctx, Entity *e, Ast *type_expr, Ast *init, Type *named_type) {
 	GB_ASSERT(e->type == nullptr);
 	GB_ASSERT(e->type == nullptr);
 	GB_ASSERT(e->kind == Entity_Constant);
 	GB_ASSERT(e->kind == Entity_Constant);
 	init = unparen_expr(init);
 	init = unparen_expr(init);
@@ -609,12 +591,12 @@ void check_const_decl(CheckerContext *ctx, Entity *e, Ast *type_expr, Ast *init,
 
 
 
 
 typedef bool TypeCheckSig(Type *t);
 typedef bool TypeCheckSig(Type *t);
-bool sig_compare(TypeCheckSig *a, Type *x, Type *y) {
+gb_internal bool sig_compare(TypeCheckSig *a, Type *x, Type *y) {
 	x = core_type(x);
 	x = core_type(x);
 	y = core_type(y);
 	y = core_type(y);
 	return (a(x) && a(y));
 	return (a(x) && a(y));
 }
 }
-bool sig_compare(TypeCheckSig *a, TypeCheckSig *b, Type *x, Type *y) {
+gb_internal bool sig_compare(TypeCheckSig *a, TypeCheckSig *b, Type *x, Type *y) {
 	x = core_type(x);
 	x = core_type(x);
 	y = core_type(y);
 	y = core_type(y);
 	if (a == b) {
 	if (a == b) {
@@ -623,7 +605,7 @@ bool sig_compare(TypeCheckSig *a, TypeCheckSig *b, Type *x, Type *y) {
 	return ((a(x) && b(y)) || (b(x) && a(y)));
 	return ((a(x) && b(y)) || (b(x) && a(y)));
 }
 }
 
 
-bool signature_parameter_similar_enough(Type *x, Type *y) {
+gb_internal bool signature_parameter_similar_enough(Type *x, Type *y) {
 	if (sig_compare(is_type_pointer, x, y)) {
 	if (sig_compare(is_type_pointer, x, y)) {
 		return true;
 		return true;
 	}
 	}
@@ -674,7 +656,7 @@ bool signature_parameter_similar_enough(Type *x, Type *y) {
 }
 }
 
 
 
 
-bool are_signatures_similar_enough(Type *a_, Type *b_) {
+gb_internal bool are_signatures_similar_enough(Type *a_, Type *b_) {
 	GB_ASSERT(a_->kind == Type_Proc);
 	GB_ASSERT(a_->kind == Type_Proc);
 	GB_ASSERT(b_->kind == Type_Proc);
 	GB_ASSERT(b_->kind == Type_Proc);
 	TypeProc *a = &a_->Proc;
 	TypeProc *a = &a_->Proc;
@@ -704,7 +686,7 @@ bool are_signatures_similar_enough(Type *a_, Type *b_) {
 	return true;
 	return true;
 }
 }
 
 
-Entity *init_entity_foreign_library(CheckerContext *ctx, Entity *e) {
+gb_internal Entity *init_entity_foreign_library(CheckerContext *ctx, Entity *e) {
 	Ast *ident = nullptr;
 	Ast *ident = nullptr;
 	Entity **foreign_library = nullptr;
 	Entity **foreign_library = nullptr;
 
 
@@ -747,7 +729,7 @@ Entity *init_entity_foreign_library(CheckerContext *ctx, Entity *e) {
 	return nullptr;
 	return nullptr;
 }
 }
 
 
-String handle_link_name(CheckerContext *ctx, Token token, String link_name, String link_prefix) {
+gb_internal String handle_link_name(CheckerContext *ctx, Token token, String link_name, String link_prefix) {
 	if (link_prefix.len > 0) {
 	if (link_prefix.len > 0) {
 		if (link_name.len > 0) {
 		if (link_name.len > 0) {
 			error(token, "'link_name' and 'link_prefix' cannot be used together");
 			error(token, "'link_name' and 'link_prefix' cannot be used together");
@@ -764,7 +746,7 @@ String handle_link_name(CheckerContext *ctx, Token token, String link_name, Stri
 	return link_name;
 	return link_name;
 }
 }
 
 
-void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) {
+gb_internal void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) {
 	GB_ASSERT(e->type == nullptr);
 	GB_ASSERT(e->type == nullptr);
 	if (d->proc_lit->kind != Ast_ProcLit) {
 	if (d->proc_lit->kind != Ast_ProcLit) {
 		// TOOD(bill): Better error message
 		// TOOD(bill): Better error message
@@ -1121,7 +1103,7 @@ void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) {
 	}
 	}
 }
 }
 
 
-void check_global_variable_decl(CheckerContext *ctx, Entity *&e, Ast *type_expr, Ast *init_expr) {
+gb_internal void check_global_variable_decl(CheckerContext *ctx, Entity *&e, Ast *type_expr, Ast *init_expr) {
 	GB_ASSERT(e->type == nullptr);
 	GB_ASSERT(e->type == nullptr);
 	GB_ASSERT(e->kind == Entity_Variable);
 	GB_ASSERT(e->kind == Entity_Variable);
 
 
@@ -1239,7 +1221,7 @@ void check_global_variable_decl(CheckerContext *ctx, Entity *&e, Ast *type_expr,
 	check_rtti_type_disallowed(e->token, e->type, "A variable declaration is using a type, %s, which has been disallowed");
 	check_rtti_type_disallowed(e->token, e->type, "A variable declaration is using a type, %s, which has been disallowed");
 }
 }
 
 
-void check_proc_group_decl(CheckerContext *ctx, Entity *&pg_entity, DeclInfo *d) {
+gb_internal void check_proc_group_decl(CheckerContext *ctx, Entity *&pg_entity, DeclInfo *d) {
 	GB_ASSERT(pg_entity->kind == Entity_ProcGroup);
 	GB_ASSERT(pg_entity->kind == Entity_ProcGroup);
 	auto *pge = &pg_entity->ProcGroup;
 	auto *pge = &pg_entity->ProcGroup;
 	String proc_group_name = pg_entity->token.string;
 	String proc_group_name = pg_entity->token.string;
@@ -1367,7 +1349,7 @@ void check_proc_group_decl(CheckerContext *ctx, Entity *&pg_entity, DeclInfo *d)
 
 
 }
 }
 
 
-void check_entity_decl(CheckerContext *ctx, Entity *e, DeclInfo *d, Type *named_type) {
+gb_internal void check_entity_decl(CheckerContext *ctx, Entity *e, DeclInfo *d, Type *named_type) {
 	if (e->state == EntityState_Resolved)  {
 	if (e->state == EntityState_Resolved)  {
 		return;
 		return;
 	}
 	}
@@ -1437,7 +1419,7 @@ struct ProcUsingVar {
 };
 };
 
 
 
 
-void check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *decl, Type *type, Ast *body) {
+gb_internal void check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *decl, Type *type, Ast *body) {
 	if (body == nullptr) {
 	if (body == nullptr) {
 		return;
 		return;
 	}
 	}
@@ -1499,8 +1481,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 +1581,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);
 			}
 			}
 
 

File diff suppressed because it is too large
+ 151 - 178
src/check_expr.cpp


+ 33 - 38
src/check_stmt.cpp

@@ -1,4 +1,4 @@
-bool is_diverging_expr(Ast *expr) {
+gb_internal bool is_diverging_expr(Ast *expr) {
 	expr = unparen_expr(expr);
 	expr = unparen_expr(expr);
 	if (expr->kind != Ast_CallExpr) {
 	if (expr->kind != Ast_CallExpr) {
 		return false;
 		return false;
@@ -23,14 +23,14 @@ bool is_diverging_expr(Ast *expr) {
 	t = base_type(t);
 	t = base_type(t);
 	return t != nullptr && t->kind == Type_Proc && t->Proc.diverging;
 	return t != nullptr && t->kind == Type_Proc && t->Proc.diverging;
 }
 }
-bool is_diverging_stmt(Ast *stmt) {
+gb_internal bool is_diverging_stmt(Ast *stmt) {
 	if (stmt->kind != Ast_ExprStmt) {
 	if (stmt->kind != Ast_ExprStmt) {
 		return false;
 		return false;
 	}
 	}
 	return is_diverging_expr(stmt->ExprStmt.expr);
 	return is_diverging_expr(stmt->ExprStmt.expr);
 }
 }
 
 
-bool contains_deferred_call(Ast *node) {
+gb_internal bool contains_deferred_call(Ast *node) {
 	if (node->viral_state_flags & ViralStateFlag_ContainsDeferredProcedure) {
 	if (node->viral_state_flags & ViralStateFlag_ContainsDeferredProcedure) {
 		return true;
 		return true;
 	}
 	}
@@ -61,7 +61,7 @@ bool contains_deferred_call(Ast *node) {
 	return false;
 	return false;
 }
 }
 
 
-void check_stmt_list(CheckerContext *ctx, Slice<Ast *> const &stmts, u32 flags) {
+gb_internal void check_stmt_list(CheckerContext *ctx, Slice<Ast *> const &stmts, u32 flags) {
 	if (stmts.count == 0) {
 	if (stmts.count == 0) {
 		return;
 		return;
 	}
 	}
@@ -137,7 +137,7 @@ void check_stmt_list(CheckerContext *ctx, Slice<Ast *> const &stmts, u32 flags)
 	}
 	}
 }
 }
 
 
-bool check_is_terminating_list(Slice<Ast *> const &stmts, String const &label) {
+gb_internal bool check_is_terminating_list(Slice<Ast *> const &stmts, String const &label) {
 	// Iterate backwards
 	// Iterate backwards
 	for (isize n = stmts.count-1; n >= 0; n--) {
 	for (isize n = stmts.count-1; n >= 0; n--) {
 		Ast *stmt = stmts[n];
 		Ast *stmt = stmts[n];
@@ -155,7 +155,7 @@ bool check_is_terminating_list(Slice<Ast *> const &stmts, String const &label) {
 	return false;
 	return false;
 }
 }
 
 
-bool check_has_break_list(Slice<Ast *> const &stmts, String const &label, bool implicit) {
+gb_internal bool check_has_break_list(Slice<Ast *> const &stmts, String const &label, bool implicit) {
 	for_array(i, stmts) {
 	for_array(i, stmts) {
 		Ast *stmt = stmts[i];
 		Ast *stmt = stmts[i];
 		if (check_has_break(stmt, label, implicit)) {
 		if (check_has_break(stmt, label, implicit)) {
@@ -166,7 +166,7 @@ bool check_has_break_list(Slice<Ast *> const &stmts, String const &label, bool i
 }
 }
 
 
 
 
-bool check_has_break(Ast *stmt, String const &label, bool implicit) {
+gb_internal bool check_has_break(Ast *stmt, String const &label, bool implicit) {
 	switch (stmt->kind) {
 	switch (stmt->kind) {
 	case Ast_BranchStmt:
 	case Ast_BranchStmt:
 		if (stmt->BranchStmt.token.kind == Token_break) {
 		if (stmt->BranchStmt.token.kind == Token_break) {
@@ -225,7 +225,7 @@ bool check_has_break(Ast *stmt, String const &label, bool implicit) {
 
 
 // NOTE(bill): The last expression has to be a 'return' statement
 // NOTE(bill): The last expression has to be a 'return' statement
 // TODO(bill): This is a mild hack and should be probably handled properly
 // TODO(bill): This is a mild hack and should be probably handled properly
-bool check_is_terminating(Ast *node, String const &label) {
+gb_internal bool check_is_terminating(Ast *node, String const &label) {
 	switch (node->kind) {
 	switch (node->kind) {
 	case_ast_node(rs, ReturnStmt, node);
 	case_ast_node(rs, ReturnStmt, node);
 		return true;
 		return true;
@@ -327,7 +327,7 @@ bool check_is_terminating(Ast *node, String const &label) {
 
 
 
 
 
 
-Type *check_assignment_variable(CheckerContext *ctx, Operand *lhs, Operand *rhs) {
+gb_internal Type *check_assignment_variable(CheckerContext *ctx, Operand *lhs, Operand *rhs) {
 	if (rhs->mode == Addressing_Invalid) {
 	if (rhs->mode == Addressing_Invalid) {
 		return nullptr;
 		return nullptr;
 	}
 	}
@@ -477,8 +477,8 @@ Type *check_assignment_variable(CheckerContext *ctx, Operand *lhs, Operand *rhs)
 }
 }
 
 
 
 
-void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags);
-void check_stmt(CheckerContext *ctx, Ast *node, u32 flags) {
+gb_internal void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags);
+gb_internal void check_stmt(CheckerContext *ctx, Ast *node, u32 flags) {
 	u32 prev_state_flags = ctx->state_flags;
 	u32 prev_state_flags = ctx->state_flags;
 
 
 	if (node->state_flags != 0) {
 	if (node->state_flags != 0) {
@@ -510,7 +510,7 @@ void check_stmt(CheckerContext *ctx, Ast *node, u32 flags) {
 }
 }
 
 
 
 
-void check_when_stmt(CheckerContext *ctx, AstWhenStmt *ws, u32 flags) {
+gb_internal void check_when_stmt(CheckerContext *ctx, AstWhenStmt *ws, u32 flags) {
 	Operand operand = {Addressing_Invalid};
 	Operand operand = {Addressing_Invalid};
 	check_expr(ctx, &operand, ws->cond);
 	check_expr(ctx, &operand, ws->cond);
 	if (operand.mode != Addressing_Constant || !is_type_boolean(operand.type)) {
 	if (operand.mode != Addressing_Constant || !is_type_boolean(operand.type)) {
@@ -539,7 +539,7 @@ void check_when_stmt(CheckerContext *ctx, AstWhenStmt *ws, u32 flags) {
 	}
 	}
 }
 }
 
 
-void check_label(CheckerContext *ctx, Ast *label, Ast *parent) {
+gb_internal void check_label(CheckerContext *ctx, Ast *label, Ast *parent) {
 	if (label == nullptr) {
 	if (label == nullptr) {
 		return;
 		return;
 	}
 	}
@@ -582,7 +582,7 @@ void check_label(CheckerContext *ctx, Ast *label, Ast *parent) {
 }
 }
 
 
 // Returns 'true' for 'continue', 'false' for 'return'
 // Returns 'true' for 'continue', 'false' for 'return'
-bool check_using_stmt_entity(CheckerContext *ctx, AstUsingStmt *us, Ast *expr, bool is_selector, Entity *e) {
+gb_internal bool check_using_stmt_entity(CheckerContext *ctx, AstUsingStmt *us, Ast *expr, bool is_selector, Entity *e) {
 	if (e == nullptr) {
 	if (e == nullptr) {
 		if (is_blank_ident(expr)) {
 		if (is_blank_ident(expr)) {
 			error(us->token, "'using' in a statement is not allowed with the blank identifier '_'");
 			error(us->token, "'using' in a statement is not allowed with the blank identifier '_'");
@@ -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;
@@ -704,7 +704,7 @@ bool check_using_stmt_entity(CheckerContext *ctx, AstUsingStmt *us, Ast *expr, b
 	return true;
 	return true;
 }
 }
 
 
-void check_inline_range_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) {
+gb_internal void check_inline_range_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) {
 	ast_node(irs, UnrollRangeStmt, node);
 	ast_node(irs, UnrollRangeStmt, node);
 	check_open_scope(ctx, node);
 	check_open_scope(ctx, node);
 
 
@@ -863,7 +863,7 @@ void check_inline_range_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) {
 	check_close_scope(ctx);
 	check_close_scope(ctx);
 }
 }
 
 
-void check_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) {
+gb_internal void check_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) {
 	ast_node(ss, SwitchStmt, node);
 	ast_node(ss, SwitchStmt, node);
 
 
 	Operand x = {};
 	Operand x = {};
@@ -1092,7 +1092,7 @@ enum TypeSwitchKind {
 	TypeSwitch_Any,
 	TypeSwitch_Any,
 };
 };
 
 
-TypeSwitchKind check_valid_type_switch_type(Type *type) {
+gb_internal TypeSwitchKind check_valid_type_switch_type(Type *type) {
 	type = type_deref(type);
 	type = type_deref(type);
 	if (is_type_union(type)) {
 	if (is_type_union(type)) {
 		return TypeSwitch_Union;
 		return TypeSwitch_Union;
@@ -1103,7 +1103,7 @@ TypeSwitchKind check_valid_type_switch_type(Type *type) {
 	return TypeSwitch_Invalid;
 	return TypeSwitch_Invalid;
 }
 }
 
 
-void check_type_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) {
+gb_internal void check_type_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) {
 	ast_node(ss, TypeSwitchStmt, node);
 	ast_node(ss, TypeSwitchStmt, node);
 	Operand x = {};
 	Operand x = {};
 
 
@@ -1237,7 +1237,7 @@ void check_type_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) {
 					GB_PANIC("Unknown type to type switch statement");
 					GB_PANIC("Unknown type to type switch statement");
 				}
 				}
 
 
-				if (type_ptr_set_exists(&seen, y.type)) {
+				if (type_ptr_set_update(&seen, y.type)) {
 					TokenPos pos = cc->token.pos;
 					TokenPos pos = cc->token.pos;
 					gbString expr_str = expr_to_string(y.expr);
 					gbString expr_str = expr_to_string(y.expr);
 					error(y.expr,
 					error(y.expr,
@@ -1248,7 +1248,6 @@ void check_type_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) {
 					gb_string_free(expr_str);
 					gb_string_free(expr_str);
 					break;
 					break;
 				}
 				}
-				ptr_set_add(&seen, y.type);
 			}
 			}
 		}
 		}
 
 
@@ -1318,7 +1317,7 @@ void check_type_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) {
 	}
 	}
 }
 }
 
 
-void check_block_stmt_for_errors(CheckerContext *ctx, Ast *body)  {
+gb_internal void check_block_stmt_for_errors(CheckerContext *ctx, Ast *body)  {
 	if (body->kind != Ast_BlockStmt) {
 	if (body->kind != Ast_BlockStmt) {
 		return;
 		return;
 	}
 	}
@@ -1377,7 +1376,7 @@ void check_block_stmt_for_errors(CheckerContext *ctx, Ast *body)  {
 	}
 	}
 }
 }
 
 
-bool all_operands_valid(Array<Operand> const &operands) {
+gb_internal bool all_operands_valid(Array<Operand> const &operands) {
 	if (any_errors()) {
 	if (any_errors()) {
 		for_array(i, operands) {
 		for_array(i, operands) {
 			if (operands[i].type == t_invalid) {
 			if (operands[i].type == t_invalid) {
@@ -1388,7 +1387,7 @@ bool all_operands_valid(Array<Operand> const &operands) {
 	return true;
 	return true;
 }
 }
 
 
-bool check_stmt_internal_builtin_proc_id(Ast *expr, BuiltinProcId *id_) {
+gb_internal bool check_stmt_internal_builtin_proc_id(Ast *expr, BuiltinProcId *id_) {
 	BuiltinProcId id = BuiltinProc_Invalid;
 	BuiltinProcId id = BuiltinProc_Invalid;
 	Entity *e = entity_of_node(expr);
 	Entity *e = entity_of_node(expr);
 	if (e != nullptr && e->kind == Entity_Builtin) {
 	if (e != nullptr && e->kind == Entity_Builtin) {
@@ -1400,7 +1399,7 @@ bool check_stmt_internal_builtin_proc_id(Ast *expr, BuiltinProcId *id_) {
 	return id != BuiltinProc_Invalid;
 	return id != BuiltinProc_Invalid;
 }
 }
 
 
-bool check_expr_is_stack_variable(Ast *expr) {
+gb_internal bool check_expr_is_stack_variable(Ast *expr) {
 	/*
 	/*
 	expr = unparen_expr(expr);
 	expr = unparen_expr(expr);
 	Entity *e = entity_of_node(expr);
 	Entity *e = entity_of_node(expr);
@@ -1419,7 +1418,7 @@ bool check_expr_is_stack_variable(Ast *expr) {
 	return false;
 	return false;
 }
 }
 
 
-void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) {
+gb_internal void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) {
 	u32 mod_flags = flags & (~Stmt_FallthroughAllowed);
 	u32 mod_flags = flags & (~Stmt_FallthroughAllowed);
 	switch (node->kind) {
 	switch (node->kind) {
 	case_ast_node(_, EmptyStmt, node); case_end;
 	case_ast_node(_, EmptyStmt, node); case_end;
@@ -1520,12 +1519,6 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) {
 		}
 		}
 	case_end;
 	case_end;
 
 
-	case_ast_node(ts, TagStmt, node);
-		// TODO(bill): Tag Statements
-		error(node, "Tag statements are not supported yet");
-		check_stmt(ctx, ts->stmt, flags);
-	case_end;
-
 	case_ast_node(as, AssignStmt, node);
 	case_ast_node(as, AssignStmt, node);
 		switch (as->op.kind) {
 		switch (as->op.kind) {
 		case Token_Eq: {
 		case Token_Eq: {
@@ -1949,6 +1942,7 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) {
 					entity = alloc_entity_variable(ctx->scope, token, type, EntityState_Resolved);
 					entity = alloc_entity_variable(ctx->scope, token, type, EntityState_Resolved);
 					entity->flags |= EntityFlag_ForValue;
 					entity->flags |= EntityFlag_ForValue;
 					entity->flags |= EntityFlag_Value;
 					entity->flags |= EntityFlag_Value;
+					entity->identifier = name;
 					if (i == addressable_index && use_by_reference_for_value) {
 					if (i == addressable_index && use_by_reference_for_value) {
 						entity->flags &= ~EntityFlag_Value;
 						entity->flags &= ~EntityFlag_Value;
 					}
 					}
@@ -1973,6 +1967,7 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) {
 
 
 			if (entity == nullptr) {
 			if (entity == nullptr) {
 				entity = alloc_entity_dummy_variable(builtin_pkg->scope, ast_token(name));
 				entity = alloc_entity_dummy_variable(builtin_pkg->scope, ast_token(name));
+				entity->identifier = name; // might not be an identifier
 			}
 			}
 
 
 			array_add(&entities, entity);
 			array_add(&entities, entity);
@@ -2370,8 +2365,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);

+ 42 - 42
src/check_type.cpp

@@ -1,6 +1,6 @@
-ParameterValue handle_parameter_value(CheckerContext *ctx, Type *in_type, Type **out_type_, Ast *expr, bool allow_caller_location);
+gb_internal ParameterValue handle_parameter_value(CheckerContext *ctx, Type *in_type, Type **out_type_, Ast *expr, bool allow_caller_location);
 
 
-void populate_using_array_index(CheckerContext *ctx, Ast *node, AstField *field, Type *t, String name, i32 idx) {
+gb_internal void populate_using_array_index(CheckerContext *ctx, Ast *node, AstField *field, Type *t, String name, i32 idx) {
 	t = base_type(t);
 	t = base_type(t);
 	GB_ASSERT(t->kind == Type_Array);
 	GB_ASSERT(t->kind == Type_Array);
 	Entity *e = scope_lookup_current(ctx->scope, name);
 	Entity *e = scope_lookup_current(ctx->scope, name);
@@ -27,7 +27,7 @@ void populate_using_array_index(CheckerContext *ctx, Ast *node, AstField *field,
 	}
 	}
 }
 }
 
 
-void populate_using_entity_scope(CheckerContext *ctx, Ast *node, AstField *field, Type *t) {
+gb_internal void populate_using_entity_scope(CheckerContext *ctx, Ast *node, AstField *field, Type *t) {
 	if (t == nullptr) {
 	if (t == nullptr) {
 		return;
 		return;
 	}
 	}
@@ -81,7 +81,7 @@ void populate_using_entity_scope(CheckerContext *ctx, Ast *node, AstField *field
 	}
 	}
 }
 }
 
 
-bool does_field_type_allow_using(Type *t) {
+gb_internal bool does_field_type_allow_using(Type *t) {
 	t = base_type(t);
 	t = base_type(t);
 	if (is_type_struct(t)) {
 	if (is_type_struct(t)) {
 		return true;
 		return true;
@@ -91,8 +91,8 @@ bool does_field_type_allow_using(Type *t) {
 	return false;
 	return false;
 }
 }
 
 
-void check_struct_fields(CheckerContext *ctx, Ast *node, Slice<Entity *> *fields, String **tags, Slice<Ast *> const &params,
-                         isize init_field_capacity, Type *struct_type, String context) {
+gb_internal void check_struct_fields(CheckerContext *ctx, Ast *node, Slice<Entity *> *fields, String **tags, Slice<Ast *> const &params,
+                                     isize init_field_capacity, Type *struct_type, String context) {
 	auto fields_array = array_make<Entity *>(heap_allocator(), 0, init_field_capacity);
 	auto fields_array = array_make<Entity *>(heap_allocator(), 0, init_field_capacity);
 	auto tags_array = array_make<String>(heap_allocator(), 0, init_field_capacity);
 	auto tags_array = array_make<String>(heap_allocator(), 0, init_field_capacity);
 
 
@@ -219,7 +219,7 @@ void check_struct_fields(CheckerContext *ctx, Ast *node, Slice<Entity *> *fields
 }
 }
 
 
 
 
-bool check_custom_align(CheckerContext *ctx, Ast *node, i64 *align_) {
+gb_internal bool check_custom_align(CheckerContext *ctx, Ast *node, i64 *align_) {
 	GB_ASSERT(align_ != nullptr);
 	GB_ASSERT(align_ != nullptr);
 	Operand o = {};
 	Operand o = {};
 	check_expr(ctx, &o, node);
 	check_expr(ctx, &o, node);
@@ -256,7 +256,7 @@ bool check_custom_align(CheckerContext *ctx, Ast *node, i64 *align_) {
 }
 }
 
 
 
 
-Entity *find_polymorphic_record_entity(CheckerContext *ctx, Type *original_type, isize param_count, Array<Operand> const &ordered_operands, bool *failure) {
+gb_internal Entity *find_polymorphic_record_entity(CheckerContext *ctx, Type *original_type, isize param_count, Array<Operand> const &ordered_operands, bool *failure) {
 	mutex_lock(&ctx->info->gen_types_mutex);
 	mutex_lock(&ctx->info->gen_types_mutex);
 	defer (mutex_unlock(&ctx->info->gen_types_mutex));
 	defer (mutex_unlock(&ctx->info->gen_types_mutex));
 
 
@@ -320,7 +320,7 @@ Entity *find_polymorphic_record_entity(CheckerContext *ctx, Type *original_type,
 }
 }
 
 
 
 
-void add_polymorphic_record_entity(CheckerContext *ctx, Ast *node, Type *named_type, Type *original_type) {
+gb_internal void add_polymorphic_record_entity(CheckerContext *ctx, Ast *node, Type *named_type, Type *original_type) {
 	GB_ASSERT(is_type_named(named_type));
 	GB_ASSERT(is_type_named(named_type));
 	gbAllocator a = heap_allocator();
 	gbAllocator a = heap_allocator();
 	Scope *s = ctx->scope->parent;
 	Scope *s = ctx->scope->parent;
@@ -358,10 +358,10 @@ void add_polymorphic_record_entity(CheckerContext *ctx, Ast *node, Type *named_t
 	mutex_unlock(&ctx->info->gen_types_mutex);
 	mutex_unlock(&ctx->info->gen_types_mutex);
 }
 }
 
 
-Type *check_record_polymorphic_params(CheckerContext *ctx, Ast *polymorphic_params,
-                                      bool *is_polymorphic_,
-                                      Ast *node, Array<Operand> *poly_operands,
-                                      Type *named_type, Type *original_type_for_poly) {
+gb_internal Type *check_record_polymorphic_params(CheckerContext *ctx, Ast *polymorphic_params,
+                                                  bool *is_polymorphic_,
+                                                  Ast *node, Array<Operand> *poly_operands,
+                                                  Type *named_type, Type *original_type_for_poly) {
 	Type *polymorphic_params_type = nullptr;
 	Type *polymorphic_params_type = nullptr;
 	bool can_check_fields = true;
 	bool can_check_fields = true;
 	GB_ASSERT(is_polymorphic_ != nullptr);
 	GB_ASSERT(is_polymorphic_ != nullptr);
@@ -540,7 +540,7 @@ Type *check_record_polymorphic_params(CheckerContext *ctx, Ast *polymorphic_para
 	return polymorphic_params_type;
 	return polymorphic_params_type;
 }
 }
 
 
-bool check_record_poly_operand_specialization(CheckerContext *ctx, Type *record_type, Array<Operand> *poly_operands, bool *is_polymorphic_) {
+gb_internal bool check_record_poly_operand_specialization(CheckerContext *ctx, Type *record_type, Array<Operand> *poly_operands, bool *is_polymorphic_) {
 	if (poly_operands == nullptr) {
 	if (poly_operands == nullptr) {
 		return false;
 		return false;
 	}
 	}
@@ -569,7 +569,7 @@ bool check_record_poly_operand_specialization(CheckerContext *ctx, Type *record_
 }
 }
 
 
 
 
-void check_struct_type(CheckerContext *ctx, Type *struct_type, Ast *node, Array<Operand> *poly_operands, Type *named_type, Type *original_type_for_poly) {
+gb_internal void check_struct_type(CheckerContext *ctx, Type *struct_type, Ast *node, Array<Operand> *poly_operands, Type *named_type, Type *original_type_for_poly) {
 	GB_ASSERT(is_type_struct(struct_type));
 	GB_ASSERT(is_type_struct(struct_type));
 	ast_node(st, StructType, node);
 	ast_node(st, StructType, node);
 
 
@@ -626,7 +626,7 @@ void check_struct_type(CheckerContext *ctx, Type *struct_type, Ast *node, Array<
 		}
 		}
 	}
 	}
 }
 }
-void check_union_type(CheckerContext *ctx, Type *union_type, Ast *node, Array<Operand> *poly_operands, Type *named_type, Type *original_type_for_poly) {
+gb_internal void check_union_type(CheckerContext *ctx, Type *union_type, Ast *node, Array<Operand> *poly_operands, Type *named_type, Type *original_type_for_poly) {
 	GB_ASSERT(is_type_union(union_type));
 	GB_ASSERT(is_type_union(union_type));
 	ast_node(ut, UnionType, node);
 	ast_node(ut, UnionType, node);
 
 
@@ -709,7 +709,7 @@ void check_union_type(CheckerContext *ctx, Type *union_type, Ast *node, Array<Op
 	}
 	}
 }
 }
 
 
-void check_enum_type(CheckerContext *ctx, Type *enum_type, Type *named_type, Ast *node) {
+gb_internal void check_enum_type(CheckerContext *ctx, Type *enum_type, Type *named_type, Ast *node) {
 	ast_node(et, EnumType, node);
 	ast_node(et, EnumType, node);
 	GB_ASSERT(is_type_enum(enum_type));
 	GB_ASSERT(is_type_enum(enum_type));
 
 
@@ -851,7 +851,7 @@ void check_enum_type(CheckerContext *ctx, Type *enum_type, Type *named_type, Ast
 	enum_type->Enum.max_value_index = max_value_index;
 	enum_type->Enum.max_value_index = max_value_index;
 }
 }
 
 
-bool is_type_valid_bit_set_range(Type *t) {
+gb_internal bool is_type_valid_bit_set_range(Type *t) {
 	if (is_type_integer(t)) {
 	if (is_type_integer(t)) {
 		return true;
 		return true;
 	}
 	}
@@ -861,7 +861,7 @@ bool is_type_valid_bit_set_range(Type *t) {
 	return false;
 	return false;
 }
 }
 
 
-void check_bit_set_type(CheckerContext *c, Type *type, Type *named_type, Ast *node) {
+gb_internal void check_bit_set_type(CheckerContext *c, Type *type, Type *named_type, Ast *node) {
 	ast_node(bs, BitSetType, node);
 	ast_node(bs, BitSetType, node);
 	GB_ASSERT(type->kind == Type_BitSet);
 	GB_ASSERT(type->kind == Type_BitSet);
 	type->BitSet.node = node;
 	type->BitSet.node = node;
@@ -1102,7 +1102,7 @@ void check_bit_set_type(CheckerContext *c, Type *type, Type *named_type, Ast *no
 }
 }
 
 
 
 
-bool check_type_specialization_to(CheckerContext *ctx, Type *specialization, Type *type, bool compound, bool modify_type) {
+gb_internal bool check_type_specialization_to(CheckerContext *ctx, Type *specialization, Type *type, bool compound, bool modify_type) {
 	if (type == nullptr ||
 	if (type == nullptr ||
 	    type == t_invalid) {
 	    type == t_invalid) {
 		return true;
 		return true;
@@ -1229,7 +1229,7 @@ bool check_type_specialization_to(CheckerContext *ctx, Type *specialization, Typ
 }
 }
 
 
 
 
-Type *determine_type_from_polymorphic(CheckerContext *ctx, Type *poly_type, Operand const &operand) {
+gb_internal Type *determine_type_from_polymorphic(CheckerContext *ctx, Type *poly_type, Operand const &operand) {
 	bool modify_type = !ctx->no_polymorphic_errors;
 	bool modify_type = !ctx->no_polymorphic_errors;
 	bool show_error = modify_type && !ctx->hide_polymorphic_errors;
 	bool show_error = modify_type && !ctx->hide_polymorphic_errors;
 	if (!is_operand_value(operand)) {
 	if (!is_operand_value(operand)) {
@@ -1256,7 +1256,7 @@ Type *determine_type_from_polymorphic(CheckerContext *ctx, Type *poly_type, Oper
 	return t_invalid;
 	return t_invalid;
 }
 }
 
 
-bool is_expr_from_a_parameter(CheckerContext *ctx, Ast *expr) {
+gb_internal bool is_expr_from_a_parameter(CheckerContext *ctx, Ast *expr) {
 	if (expr == nullptr) {
 	if (expr == nullptr) {
 		return false;
 		return false;
 	}
 	}
@@ -1275,7 +1275,7 @@ bool is_expr_from_a_parameter(CheckerContext *ctx, Ast *expr) {
 }
 }
 
 
 
 
-ParameterValue handle_parameter_value(CheckerContext *ctx, Type *in_type, Type **out_type_, Ast *expr, bool allow_caller_location) {
+gb_internal ParameterValue handle_parameter_value(CheckerContext *ctx, Type *in_type, Type **out_type_, Ast *expr, bool allow_caller_location) {
 	ParameterValue param_value = {};
 	ParameterValue param_value = {};
 	param_value.original_ast_expr = expr;
 	param_value.original_ast_expr = expr;
 	if (expr == nullptr) {
 	if (expr == nullptr) {
@@ -1370,7 +1370,7 @@ ParameterValue handle_parameter_value(CheckerContext *ctx, Type *in_type, Type *
 }
 }
 
 
 
 
-Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_params, bool *is_variadic_, isize *variadic_index_, bool *success_, isize *specialization_count_, Array<Operand> *operands) {
+gb_internal Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_params, bool *is_variadic_, isize *variadic_index_, bool *success_, isize *specialization_count_, Array<Operand> *operands) {
 	if (_params == nullptr) {
 	if (_params == nullptr) {
 		return nullptr;
 		return nullptr;
 	}
 	}
@@ -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 &&
@@ -1814,7 +1814,7 @@ Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_params, bool *is
 	return tuple;
 	return tuple;
 }
 }
 
 
-Type *check_get_results(CheckerContext *ctx, Scope *scope, Ast *_results) {
+gb_internal Type *check_get_results(CheckerContext *ctx, Scope *scope, Ast *_results) {
 	if (_results == nullptr) {
 	if (_results == nullptr) {
 		return nullptr;
 		return nullptr;
 	}
 	}
@@ -1928,7 +1928,7 @@ Type *check_get_results(CheckerContext *ctx, Scope *scope, Ast *_results) {
 
 
 
 
 // NOTE(bill): 'operands' is for generating non generic procedure type
 // NOTE(bill): 'operands' is for generating non generic procedure type
-bool check_procedure_type(CheckerContext *ctx, Type *type, Ast *proc_type_node, Array<Operand> *operands) {
+gb_internal bool check_procedure_type(CheckerContext *ctx, Type *type, Ast *proc_type_node, Array<Operand> *operands) {
 	ast_node(pt, ProcType, proc_type_node);
 	ast_node(pt, ProcType, proc_type_node);
 
 
 	if (ctx->polymorphic_scope == nullptr && ctx->allow_polymorphic_types) {
 	if (ctx->polymorphic_scope == nullptr && ctx->allow_polymorphic_types) {
@@ -2084,7 +2084,7 @@ bool check_procedure_type(CheckerContext *ctx, Type *type, Ast *proc_type_node,
 }
 }
 
 
 
 
-i64 check_array_count(CheckerContext *ctx, Operand *o, Ast *e) {
+gb_internal i64 check_array_count(CheckerContext *ctx, Operand *o, Ast *e) {
 	if (e == nullptr) {
 	if (e == nullptr) {
 		return 0;
 		return 0;
 	}
 	}
@@ -2169,7 +2169,7 @@ i64 check_array_count(CheckerContext *ctx, Operand *o, Ast *e) {
 	return 0;
 	return 0;
 }
 }
 
 
-Type *make_optional_ok_type(Type *value, bool typed) {
+gb_internal Type *make_optional_ok_type(Type *value, bool typed) {
 	gbAllocator a = permanent_allocator();
 	gbAllocator a = permanent_allocator();
 	Type *t = alloc_type_tuple();
 	Type *t = alloc_type_tuple();
 	slice_init(&t->Tuple.variables, a, 2);
 	slice_init(&t->Tuple.variables, a, 2);
@@ -2185,7 +2185,7 @@ enum : i64 {
 	MAP_CACHE_LINE_SIZE = 1 << MAP_CACHE_LINE_LOG2
 	MAP_CACHE_LINE_SIZE = 1 << MAP_CACHE_LINE_LOG2
 };
 };
 GB_STATIC_ASSERT(MAP_CACHE_LINE_SIZE >= 64);
 GB_STATIC_ASSERT(MAP_CACHE_LINE_SIZE >= 64);
-void map_cell_size_and_len(Type *type, i64 *size_, i64 *len_) {
+gb_internal void map_cell_size_and_len(Type *type, i64 *size_, i64 *len_) {
 	i64 elem_sz = type_size_of(type);
 	i64 elem_sz = type_size_of(type);
 
 
 	i64 len = 1;
 	i64 len = 1;
@@ -2197,7 +2197,7 @@ void map_cell_size_and_len(Type *type, i64 *size_, i64 *len_) {
 	if (len_)  *len_ = len;
 	if (len_)  *len_ = len;
 }
 }
 
 
-void init_map_internal_types(Type *type) {
+gb_internal void init_map_internal_types(Type *type) {
 	GB_ASSERT(type->kind == Type_Map);
 	GB_ASSERT(type->kind == Type_Map);
 	GB_ASSERT(t_allocator != nullptr);
 	GB_ASSERT(t_allocator != nullptr);
 	if (type->Map.lookup_result_type != nullptr) return;
 	if (type->Map.lookup_result_type != nullptr) return;
@@ -2210,7 +2210,7 @@ void init_map_internal_types(Type *type) {
 	type->Map.lookup_result_type = make_optional_ok_type(value);
 	type->Map.lookup_result_type = make_optional_ok_type(value);
 }
 }
 
 
-void add_map_key_type_dependencies(CheckerContext *ctx, Type *key) {
+gb_internal void add_map_key_type_dependencies(CheckerContext *ctx, Type *key) {
 	key = core_type(key);
 	key = core_type(key);
 
 
 	if (is_type_cstring(key)) {
 	if (is_type_cstring(key)) {
@@ -2249,7 +2249,7 @@ void add_map_key_type_dependencies(CheckerContext *ctx, Type *key) {
 	}
 	}
 }
 }
 
 
-void check_map_type(CheckerContext *ctx, Type *type, Ast *node) {
+gb_internal void check_map_type(CheckerContext *ctx, Type *type, Ast *node) {
 	GB_ASSERT(type->kind == Type_Map);
 	GB_ASSERT(type->kind == Type_Map);
 	ast_node(mt, MapType, node);
 	ast_node(mt, MapType, node);
 
 
@@ -2282,7 +2282,7 @@ void check_map_type(CheckerContext *ctx, Type *type, Ast *node) {
 	// error(node, "'map' types are not yet implemented");
 	// error(node, "'map' types are not yet implemented");
 }
 }
 
 
-void check_matrix_type(CheckerContext *ctx, Type **type, Ast *node) {
+gb_internal void check_matrix_type(CheckerContext *ctx, Type **type, Ast *node) {
 	ast_node(mt, MatrixType, node);
 	ast_node(mt, MatrixType, node);
 	
 	
 	Operand row = {};
 	Operand row = {};
@@ -2346,7 +2346,7 @@ type_assign:;
 
 
 
 
 
 
-Type *make_soa_struct_internal(CheckerContext *ctx, Ast *array_typ_expr, Ast *elem_expr, Type *elem, i64 count, Type *generic_type, StructSoaKind soa_kind) {
+gb_internal Type *make_soa_struct_internal(CheckerContext *ctx, Ast *array_typ_expr, Ast *elem_expr, Type *elem, i64 count, Type *generic_type, StructSoaKind soa_kind) {
 	Type *bt_elem = base_type(elem);
 	Type *bt_elem = base_type(elem);
 
 
 	bool is_polymorphic = is_type_polymorphic(elem);
 	bool is_polymorphic = is_type_polymorphic(elem);
@@ -2501,20 +2501,20 @@ Type *make_soa_struct_internal(CheckerContext *ctx, Ast *array_typ_expr, Ast *el
 }
 }
 
 
 
 
-Type *make_soa_struct_fixed(CheckerContext *ctx, Ast *array_typ_expr, Ast *elem_expr, Type *elem, i64 count, Type *generic_type) {
+gb_internal Type *make_soa_struct_fixed(CheckerContext *ctx, Ast *array_typ_expr, Ast *elem_expr, Type *elem, i64 count, Type *generic_type) {
 	return make_soa_struct_internal(ctx, array_typ_expr, elem_expr, elem, count, generic_type, StructSoa_Fixed);
 	return make_soa_struct_internal(ctx, array_typ_expr, elem_expr, elem, count, generic_type, StructSoa_Fixed);
 }
 }
 
 
-Type *make_soa_struct_slice(CheckerContext *ctx, Ast *array_typ_expr, Ast *elem_expr, Type *elem) {
+gb_internal Type *make_soa_struct_slice(CheckerContext *ctx, Ast *array_typ_expr, Ast *elem_expr, Type *elem) {
 	return make_soa_struct_internal(ctx, array_typ_expr, elem_expr, elem, -1, nullptr, StructSoa_Slice);
 	return make_soa_struct_internal(ctx, array_typ_expr, elem_expr, elem, -1, nullptr, StructSoa_Slice);
 }
 }
 
 
 
 
-Type *make_soa_struct_dynamic_array(CheckerContext *ctx, Ast *array_typ_expr, Ast *elem_expr, Type *elem) {
+gb_internal Type *make_soa_struct_dynamic_array(CheckerContext *ctx, Ast *array_typ_expr, Ast *elem_expr, Type *elem) {
 	return make_soa_struct_internal(ctx, array_typ_expr, elem_expr, elem, -1, nullptr, StructSoa_Dynamic);
 	return make_soa_struct_internal(ctx, array_typ_expr, elem_expr, elem, -1, nullptr, StructSoa_Dynamic);
 }
 }
 
 
-bool check_type_internal(CheckerContext *ctx, Ast *e, Type **type, Type *named_type) {
+gb_internal bool check_type_internal(CheckerContext *ctx, Ast *e, Type **type, Type *named_type) {
 	GB_ASSERT_NOT_NULL(type);
 	GB_ASSERT_NOT_NULL(type);
 	if (e == nullptr) {
 	if (e == nullptr) {
 		*type = t_invalid;
 		*type = t_invalid;
@@ -2997,7 +2997,7 @@ bool check_type_internal(CheckerContext *ctx, Ast *e, Type **type, Type *named_t
 	return false;
 	return false;
 }
 }
 
 
-Type *check_type(CheckerContext *ctx, Ast *e) {
+gb_internal Type *check_type(CheckerContext *ctx, Ast *e) {
 	CheckerContext c = *ctx;
 	CheckerContext c = *ctx;
 	c.type_path = new_checker_type_path();
 	c.type_path = new_checker_type_path();
 	defer (destroy_checker_type_path(c.type_path));
 	defer (destroy_checker_type_path(c.type_path));
@@ -3005,7 +3005,7 @@ Type *check_type(CheckerContext *ctx, Ast *e) {
 	return check_type_expr(&c, e, nullptr);
 	return check_type_expr(&c, e, nullptr);
 }
 }
 
 
-Type *check_type_expr(CheckerContext *ctx, Ast *e, Type *named_type) {
+gb_internal Type *check_type_expr(CheckerContext *ctx, Ast *e, Type *named_type) {
 	Type *type = nullptr;
 	Type *type = nullptr;
 	bool ok = check_type_internal(ctx, e, &type, named_type);
 	bool ok = check_type_internal(ctx, e, &type, named_type);
 
 

File diff suppressed because it is too large
+ 175 - 187
src/checker.cpp


+ 45 - 48
src/checker.hpp

@@ -20,7 +20,7 @@ struct ExprInfo {
 	ExactValue     value;
 	ExactValue     value;
 };
 };
 
 
-gb_inline ExprInfo *make_expr_info(AddressingMode mode, Type *type, ExactValue const &value, bool is_lhs) {
+gb_internal gb_inline ExprInfo *make_expr_info(AddressingMode mode, Type *type, ExactValue const &value, bool is_lhs) {
 	ExprInfo *ei = gb_alloc_item(permanent_allocator(), ExprInfo);
 	ExprInfo *ei = gb_alloc_item(permanent_allocator(), ExprInfo);
 	ei->mode   = mode;
 	ei->mode   = mode;
 	ei->type   = type;
 	ei->type   = type;
@@ -130,7 +130,7 @@ struct AttributeContext {
 	String enable_target_feature;  // will be enabled for the procedure only
 	String enable_target_feature;  // will be enabled for the procedure only
 };
 };
 
 
-AttributeContext make_attribute_context(String link_prefix) {
+gb_internal gb_inline AttributeContext make_attribute_context(String link_prefix) {
 	AttributeContext ac = {};
 	AttributeContext ac = {};
 	ac.link_prefix = link_prefix;
 	ac.link_prefix = link_prefix;
 	return ac;
 	return ac;
@@ -139,7 +139,7 @@ AttributeContext make_attribute_context(String link_prefix) {
 #define DECL_ATTRIBUTE_PROC(_name) bool _name(CheckerContext *c, Ast *elem, String name, Ast *value, AttributeContext *ac)
 #define DECL_ATTRIBUTE_PROC(_name) bool _name(CheckerContext *c, Ast *elem, String name, Ast *value, AttributeContext *ac)
 typedef DECL_ATTRIBUTE_PROC(DeclAttributeProc);
 typedef DECL_ATTRIBUTE_PROC(DeclAttributeProc);
 
 
-void check_decl_attributes(CheckerContext *c, Array<Ast *> const &attributes, DeclAttributeProc *proc, AttributeContext *ac);
+gb_internal void check_decl_attributes(CheckerContext *c, Array<Ast *> const &attributes, DeclAttributeProc *proc, AttributeContext *ac);
 
 
 
 
 // DeclInfo is used to store information of certain declarations to allow for "any order" usage
 // DeclInfo is used to store information of certain declarations to allow for "any order" usage
@@ -158,6 +158,7 @@ struct DeclInfo {
 	bool          is_using;
 	bool          is_using;
 	bool          where_clauses_evaluated;
 	bool          where_clauses_evaluated;
 	bool          proc_checked;
 	bool          proc_checked;
+	BlockingMutex proc_checked_mutex;
 	isize         defer_used;
 	isize         defer_used;
 	bool          defer_use_checked;
 	bool          defer_use_checked;
 
 
@@ -377,15 +378,19 @@ struct CheckerInfo {
 };
 };
 
 
 struct CheckerContext {
 struct CheckerContext {
+	// Order matters here
+	BlockingMutex  mutex;
 	Checker *      checker;
 	Checker *      checker;
 	CheckerInfo *  info;
 	CheckerInfo *  info;
+
 	AstPackage *   pkg;
 	AstPackage *   pkg;
 	AstFile *      file;
 	AstFile *      file;
 	Scope *        scope;
 	Scope *        scope;
 	DeclInfo *     decl;
 	DeclInfo *     decl;
 
 
+	// Order doesn't matter after this
 	u32            state_flags;
 	u32            state_flags;
-	bool           in_defer; // TODO(bill): Actually handle correctly
+	bool           in_defer;
 	Type *         type_hint;
 	Type *         type_hint;
 
 
 	String         proc_name;
 	String         proc_name;
@@ -396,9 +401,7 @@ struct CheckerContext {
 	ForeignContext foreign_context;
 	ForeignContext foreign_context;
 
 
 	CheckerTypePath *type_path;
 	CheckerTypePath *type_path;
-	isize            type_level; // TODO(bill): Actually handle correctly
-	CheckerPolyPath *poly_path;
-	isize            poly_level; // TODO(bill): Actually handle correctly
+	isize            type_level;
 
 
 	UntypedExprInfoMap *untyped;
 	UntypedExprInfoMap *untyped;
 
 
@@ -443,59 +446,53 @@ gb_global AstPackage *config_pkg      = nullptr;
 
 
 
 
 // CheckerInfo API
 // CheckerInfo API
-TypeAndValue type_and_value_of_expr (Ast *expr);
-Type *       type_of_expr           (Ast *expr);
-Entity *     implicit_entity_of_node(Ast *clause);
-DeclInfo *   decl_info_of_ident     (Ast *ident);
-DeclInfo *   decl_info_of_entity    (Entity * e);
-AstFile *    ast_file_of_filename   (CheckerInfo *i, String   filename);
+gb_internal TypeAndValue type_and_value_of_expr (Ast *expr);
+gb_internal Type *       type_of_expr           (Ast *expr);
+gb_internal Entity *     implicit_entity_of_node(Ast *clause);
+gb_internal DeclInfo *   decl_info_of_ident     (Ast *ident);
+gb_internal DeclInfo *   decl_info_of_entity    (Entity * e);
+gb_internal AstFile *    ast_file_of_filename   (CheckerInfo *i, String   filename);
 // IMPORTANT: Only to use once checking is done
 // IMPORTANT: Only to use once checking is done
-isize        type_info_index        (CheckerInfo *i, Type *type, bool error_on_failure);
+gb_internal isize        type_info_index        (CheckerInfo *i, Type *type, bool error_on_failure);
 
 
 // Will return nullptr if not found
 // Will return nullptr if not found
-Entity *entity_of_node(Ast *expr);
-
-
-Entity *scope_lookup_current(Scope *s, String const &name);
-Entity *scope_lookup (Scope *s, String const &name);
-void    scope_lookup_parent (Scope *s, String const &name, Scope **scope_, Entity **entity_);
-Entity *scope_insert (Scope *s, Entity *entity, bool use_mutex=true);
+gb_internal Entity *entity_of_node(Ast *expr);
 
 
 
 
-void      add_type_and_value      (CheckerInfo *i, Ast *expression, AddressingMode mode, Type *type, ExactValue value);
-ExprInfo *check_get_expr_info     (CheckerContext *c, Ast *expr);
-void      add_untyped             (CheckerContext *c, Ast *expression, AddressingMode mode, Type *basic_type, ExactValue value);
-void      add_entity_use          (CheckerContext *c, Ast *identifier, Entity *entity);
-void      add_implicit_entity     (CheckerContext *c, Ast *node, Entity *e);
-void      add_entity_and_decl_info(CheckerContext *c, Ast *identifier, Entity *e, DeclInfo *d, bool is_exported=true);
-void      add_type_info_type      (CheckerContext *c, Type *t);
+gb_internal Entity *scope_lookup_current(Scope *s, String const &name);
+gb_internal Entity *scope_lookup (Scope *s, String const &name);
+gb_internal void    scope_lookup_parent (Scope *s, String const &name, Scope **scope_, Entity **entity_);
+gb_internal Entity *scope_insert (Scope *s, Entity *entity, bool use_mutex=true);
 
 
-void check_add_import_decl(CheckerContext *c, Ast *decl);
-void check_add_foreign_import_decl(CheckerContext *c, Ast *decl);
 
 
+gb_internal void      add_type_and_value      (CheckerInfo *i, Ast *expression, AddressingMode mode, Type *type, ExactValue value);
+gb_internal ExprInfo *check_get_expr_info     (CheckerContext *c, Ast *expr);
+gb_internal void      add_untyped             (CheckerContext *c, Ast *expression, AddressingMode mode, Type *basic_type, ExactValue value);
+gb_internal void      add_entity_use          (CheckerContext *c, Ast *identifier, Entity *entity);
+gb_internal void      add_implicit_entity     (CheckerContext *c, Ast *node, Entity *e);
+gb_internal void      add_entity_and_decl_info(CheckerContext *c, Ast *identifier, Entity *e, DeclInfo *d, bool is_exported=true);
+gb_internal void      add_type_info_type      (CheckerContext *c, Type *t);
 
 
-void check_entity_decl(CheckerContext *c, Entity *e, DeclInfo *d, Type *named_type);
-void check_const_decl(CheckerContext *c, Entity *e, Ast *type_expr, Ast *init_expr, Type *named_type);
-void check_type_decl(CheckerContext *c, Entity *e, Ast *type_expr, Type *def);
+gb_internal void check_add_import_decl(CheckerContext *c, Ast *decl);
+gb_internal void check_add_foreign_import_decl(CheckerContext *c, Ast *decl);
 
 
-bool check_arity_match(CheckerContext *c, AstValueDecl *vd, bool is_global = false);
-void check_collect_entities(CheckerContext *c, Slice<Ast *> const &nodes);
-void check_collect_entities_from_when_stmt(CheckerContext *c, AstWhenStmt *ws);
-void check_delayed_file_import_entity(CheckerContext *c, Ast *decl);
 
 
-CheckerTypePath *new_checker_type_path();
-void destroy_checker_type_path(CheckerTypePath *tp);
+gb_internal void check_entity_decl(CheckerContext *c, Entity *e, DeclInfo *d, Type *named_type);
+gb_internal void check_const_decl(CheckerContext *c, Entity *e, Ast *type_expr, Ast *init_expr, Type *named_type);
+gb_internal void check_type_decl(CheckerContext *c, Entity *e, Ast *type_expr, Type *def);
 
 
-void    check_type_path_push(CheckerContext *c, Entity *e);
-Entity *check_type_path_pop (CheckerContext *c);
+gb_internal bool check_arity_match(CheckerContext *c, AstValueDecl *vd, bool is_global = false);
+gb_internal void check_collect_entities(CheckerContext *c, Slice<Ast *> const &nodes);
+gb_internal void check_collect_entities_from_when_stmt(CheckerContext *c, AstWhenStmt *ws);
+gb_internal void check_delayed_file_import_entity(CheckerContext *c, Ast *decl);
 
 
-CheckerPolyPath *new_checker_poly_path();
-void destroy_checker_poly_path(CheckerPolyPath *);
+gb_internal CheckerTypePath *new_checker_type_path();
+gb_internal void destroy_checker_type_path(CheckerTypePath *tp);
 
 
-void  check_poly_path_push(CheckerContext *c, Type *t);
-Type *check_poly_path_pop (CheckerContext *c);
+gb_internal void    check_type_path_push(CheckerContext *c, Entity *e);
+gb_internal Entity *check_type_path_pop (CheckerContext *c);
 
 
-void init_core_context(Checker *c);
-void init_mem_allocator(Checker *c);
+gb_internal void init_core_context(Checker *c);
+gb_internal void init_mem_allocator(Checker *c);
 
 
-void add_untyped_expressions(CheckerInfo *cinfo, UntypedExprInfoMap *untyped);
+gb_internal void add_untyped_expressions(CheckerInfo *cinfo, UntypedExprInfoMap *untyped);

+ 54 - 45
src/common.cpp

@@ -29,14 +29,14 @@
 #include <string.h>
 #include <string.h>
 #include <atomic> // Because I wanted the C++11 memory order semantics, of which gb.h does not offer (because it was a C89 library)
 #include <atomic> // Because I wanted the C++11 memory order semantics, of which gb.h does not offer (because it was a C89 library)
 
 
-gbAllocator heap_allocator(void);
+gb_internal gbAllocator heap_allocator(void);
 
 
 #define for_array(index_, array_) for (isize index_ = 0; index_ < (array_).count; index_++)
 #define for_array(index_, array_) for (isize index_ = 0; index_ < (array_).count; index_++)
 
 
-i32 next_pow2(i32 n);
-i64 next_pow2(i64 n);
-isize next_pow2_isize(isize n);
-void debugf(char const *fmt, ...);
+gb_internal i32 next_pow2(i32 n);
+gb_internal i64 next_pow2(i64 n);
+gb_internal isize next_pow2_isize(isize n);
+gb_internal void debugf(char const *fmt, ...);
 
 
 #if defined(GB_SYSTEM_WINDOWS) && defined(GB_ARCH_32_BIT)
 #if defined(GB_SYSTEM_WINDOWS) && defined(GB_ARCH_32_BIT)
 #error Odin on Windows requires a 64-bit build-system. The 'Developer Command Prompt' for VS still defaults to 32-bit shell. The 64-bit shell can be found under the name 'x64 Native Tools Command Prompt' for VS. For more information, please see https://odin-lang.org/docs/install/#for-windows
 #error Odin on Windows requires a 64-bit build-system. The 'Developer Command Prompt' for VS still defaults to 32-bit shell. The 64-bit shell can be found under the name 'x64 Native Tools Command Prompt' for VS. For more information, please see https://odin-lang.org/docs/install/#for-windows
@@ -50,15 +50,19 @@ void debugf(char const *fmt, ...);
 #include "string.cpp"
 #include "string.cpp"
 #include "range_cache.cpp"
 #include "range_cache.cpp"
 
 
+#if defined(GB_SYSTEM_WINDOWS)
+	#pragma warning(push)
+	#pragma warning(disable: 4505)
+#endif
 
 
-bool is_power_of_two(i64 x) {
+gb_internal gb_inline bool is_power_of_two(i64 x) {
 	if (x <= 0) {
 	if (x <= 0) {
 		return false;
 		return false;
 	}
 	}
 	return !(x & (x-1));
 	return !(x & (x-1));
 }
 }
 
 
-int isize_cmp(isize x, isize y) {
+gb_internal int isize_cmp(isize x, isize y) {
 	if (x < y) {
 	if (x < y) {
 		return -1;
 		return -1;
 	} else if (x > y) {
 	} else if (x > y) {
@@ -66,7 +70,7 @@ int isize_cmp(isize x, isize y) {
 	}
 	}
 	return 0;
 	return 0;
 }
 }
-int u64_cmp(u64 x, u64 y) {
+gb_internal int u64_cmp(u64 x, u64 y) {
 	if (x < y) {
 	if (x < y) {
 		return -1;
 		return -1;
 	} else if (x > y) {
 	} else if (x > y) {
@@ -74,7 +78,7 @@ int u64_cmp(u64 x, u64 y) {
 	}
 	}
 	return 0;
 	return 0;
 }
 }
-int i64_cmp(i64 x, i64 y) {
+gb_internal int i64_cmp(i64 x, i64 y) {
 	if (x < y) {
 	if (x < y) {
 		return -1;
 		return -1;
 	} else if (x > y) {
 	} else if (x > y) {
@@ -82,7 +86,7 @@ int i64_cmp(i64 x, i64 y) {
 	}
 	}
 	return 0;
 	return 0;
 }
 }
-int i32_cmp(i32 x, i32 y) {
+gb_internal int i32_cmp(i32 x, i32 y) {
 	if (x < y) {
 	if (x < y) {
 		return -1;
 		return -1;
 	} else if (x > y) {
 	} else if (x > y) {
@@ -91,7 +95,7 @@ int i32_cmp(i32 x, i32 y) {
 	return 0;
 	return 0;
 }
 }
 
 
-u32 fnv32a(void const *data, isize len) {
+gb_internal u32 fnv32a(void const *data, isize len) {
 	u8 const *bytes = cast(u8 const *)data;
 	u8 const *bytes = cast(u8 const *)data;
 	u32 h = 0x811c9dc5;
 	u32 h = 0x811c9dc5;
 	
 	
@@ -112,7 +116,7 @@ u32 fnv32a(void const *data, isize len) {
 	return h;
 	return h;
 }
 }
 
 
-u64 fnv64a(void const *data, isize len) {
+gb_internal u64 fnv64a(void const *data, isize len) {
 	u8 const *bytes = cast(u8 const *)data;
 	u8 const *bytes = cast(u8 const *)data;
 	u64 h = 0xcbf29ce484222325ull;
 	u64 h = 0xcbf29ce484222325ull;
 	
 	
@@ -133,7 +137,7 @@ u64 fnv64a(void const *data, isize len) {
 	return h;
 	return h;
 }
 }
 
 
-u64 u64_digit_value(Rune r) {
+gb_internal u64 u64_digit_value(Rune r) {
 	switch (r) {
 	switch (r) {
 	case '0': return 0;
 	case '0': return 0;
 	case '1': return 1;
 	case '1': return 1;
@@ -162,7 +166,7 @@ u64 u64_digit_value(Rune r) {
 }
 }
 
 
 
 
-u64 u64_from_string(String string) {
+gb_internal u64 u64_from_string(String string) {
 	u64 base = 10;
 	u64 base = 10;
 	bool has_prefix = false;
 	bool has_prefix = false;
 	if (string.len > 2 && string[0] == '0') {
 	if (string.len > 2 && string[0] == '0') {
@@ -205,7 +209,7 @@ gb_global char const global_num_to_char_table[] =
 	"abcdefghijklmnopqrstuvwxyz"
 	"abcdefghijklmnopqrstuvwxyz"
 	"@$";
 	"@$";
 
 
-String u64_to_string(u64 v, char *out_buf, isize out_buf_len) {
+gb_internal String u64_to_string(u64 v, char *out_buf, isize out_buf_len) {
 	char buf[32] = {0};
 	char buf[32] = {0};
 	isize i = gb_size_of(buf);
 	isize i = gb_size_of(buf);
 
 
@@ -220,7 +224,7 @@ String u64_to_string(u64 v, char *out_buf, isize out_buf_len) {
 	gb_memmove(out_buf, &buf[i], len);
 	gb_memmove(out_buf, &buf[i], len);
 	return make_string(cast(u8 *)out_buf, len);
 	return make_string(cast(u8 *)out_buf, len);
 }
 }
-String i64_to_string(i64 a, char *out_buf, isize out_buf_len) {
+gb_internal String i64_to_string(i64 a, char *out_buf, isize out_buf_len) {
 	char buf[32] = {0};
 	char buf[32] = {0};
 	isize i = gb_size_of(buf);
 	isize i = gb_size_of(buf);
 	bool negative = false;
 	bool negative = false;
@@ -282,17 +286,17 @@ gb_global u64 const unsigned_integer_maxs[] = {
 };
 };
 
 
 
 
-bool add_overflow_u64(u64 x, u64 y, u64 *result) {
+gb_internal bool add_overflow_u64(u64 x, u64 y, u64 *result) {
 	*result = x + y;
 	*result = x + y;
 	return *result < x || *result < y;
 	return *result < x || *result < y;
 }
 }
 
 
-bool sub_overflow_u64(u64 x, u64 y, u64 *result) {
+gb_internal bool sub_overflow_u64(u64 x, u64 y, u64 *result) {
 	*result = x - y;
 	*result = x - y;
 	return *result > x;
 	return *result > x;
 }
 }
 
 
-void mul_overflow_u64(u64 x, u64 y, u64 *lo, u64 *hi) {
+gb_internal void mul_overflow_u64(u64 x, u64 y, u64 *lo, u64 *hi) {
 #if defined(GB_COMPILER_MSVC) && defined(GB_ARCH_64_BIT)
 #if defined(GB_COMPILER_MSVC) && defined(GB_ARCH_64_BIT)
 	*lo = _umul128(x, y, hi);
 	*lo = _umul128(x, y, hi);
 #else
 #else
@@ -342,7 +346,7 @@ struct StringIntern {
 PtrMap<uintptr, StringIntern *> string_intern_map = {}; // Key: u64
 PtrMap<uintptr, StringIntern *> string_intern_map = {}; // Key: u64
 gb_global Arena string_intern_arena = {};
 gb_global Arena string_intern_arena = {};
 
 
-char const *string_intern(char const *text, isize len) {
+gb_internal char const *string_intern(char const *text, isize len) {
 	u64 hash = gb_fnv64a(text, len);
 	u64 hash = gb_fnv64a(text, len);
 	uintptr key = cast(uintptr)(hash ? hash : 1);
 	uintptr key = cast(uintptr)(hash ? hash : 1);
 	StringIntern **found = map_get(&string_intern_map, key);
 	StringIntern **found = map_get(&string_intern_map, key);
@@ -363,18 +367,18 @@ char const *string_intern(char const *text, isize len) {
 	return new_intern->str;
 	return new_intern->str;
 }
 }
 
 
-char const *string_intern(String const &string) {
+gb_internal char const *string_intern(String const &string) {
 	return string_intern(cast(char const *)string.text, string.len);
 	return string_intern(cast(char const *)string.text, string.len);
 }
 }
 
 
-void init_string_interner(void) {
+gb_internal void init_string_interner(void) {
 	map_init(&string_intern_map, heap_allocator());
 	map_init(&string_intern_map, heap_allocator());
 }
 }
 
 
 
 
 
 
 
 
-i32 next_pow2(i32 n) {
+gb_internal i32 next_pow2(i32 n) {
 	if (n <= 0) {
 	if (n <= 0) {
 		return 0;
 		return 0;
 	}
 	}
@@ -387,7 +391,7 @@ i32 next_pow2(i32 n) {
 	n++;
 	n++;
 	return n;
 	return n;
 }
 }
-i64 next_pow2(i64 n) {
+gb_internal i64 next_pow2(i64 n) {
 	if (n <= 0) {
 	if (n <= 0) {
 		return 0;
 		return 0;
 	}
 	}
@@ -401,7 +405,7 @@ i64 next_pow2(i64 n) {
 	n++;
 	n++;
 	return n;
 	return n;
 }
 }
-isize next_pow2_isize(isize n) {
+gb_internal isize next_pow2_isize(isize n) {
 	if (n <= 0) {
 	if (n <= 0) {
 		return 0;
 		return 0;
 	}
 	}
@@ -417,7 +421,7 @@ isize next_pow2_isize(isize n) {
 	n++;
 	n++;
 	return n;
 	return n;
 }
 }
-u32 next_pow2_u32(u32 n) {
+gb_internal u32 next_pow2_u32(u32 n) {
 	if (n == 0) {
 	if (n == 0) {
 		return 0;
 		return 0;
 	}
 	}
@@ -432,7 +436,7 @@ u32 next_pow2_u32(u32 n) {
 }
 }
 
 
 
 
-i32 bit_set_count(u32 x) {
+gb_internal i32 bit_set_count(u32 x) {
 	x -= ((x >> 1) & 0x55555555);
 	x -= ((x >> 1) & 0x55555555);
 	x = (((x >> 2) & 0x33333333) + (x & 0x33333333));
 	x = (((x >> 2) & 0x33333333) + (x & 0x33333333));
 	x = (((x >> 4) + x) & 0x0f0f0f0f);
 	x = (((x >> 4) + x) & 0x0f0f0f0f);
@@ -442,13 +446,13 @@ i32 bit_set_count(u32 x) {
 	return cast(i32)(x & 0x0000003f);
 	return cast(i32)(x & 0x0000003f);
 }
 }
 
 
-i64 bit_set_count(u64 x) {
+gb_internal i64 bit_set_count(u64 x) {
 	u32 a = *(cast(u32 *)&x);
 	u32 a = *(cast(u32 *)&x);
 	u32 b = *(cast(u32 *)&x + 1);
 	u32 b = *(cast(u32 *)&x + 1);
 	return bit_set_count(a) + bit_set_count(b);
 	return bit_set_count(a) + bit_set_count(b);
 }
 }
 
 
-u32 floor_log2(u32 x) {
+gb_internal u32 floor_log2(u32 x) {
 	x |= x >> 1;
 	x |= x >> 1;
 	x |= x >> 2;
 	x |= x >> 2;
 	x |= x >> 4;
 	x |= x >> 4;
@@ -457,7 +461,7 @@ u32 floor_log2(u32 x) {
 	return cast(u32)(bit_set_count(x) - 1);
 	return cast(u32)(bit_set_count(x) - 1);
 }
 }
 
 
-u64 floor_log2(u64 x) {
+gb_internal u64 floor_log2(u64 x) {
 	x |= x >> 1;
 	x |= x >> 1;
 	x |= x >> 2;
 	x |= x >> 2;
 	x |= x >> 4;
 	x |= x >> 4;
@@ -468,7 +472,7 @@ u64 floor_log2(u64 x) {
 }
 }
 
 
 
 
-u32 ceil_log2(u32 x) {
+gb_internal u32 ceil_log2(u32 x) {
 	i32 y = cast(i32)(x & (x-1));
 	i32 y = cast(i32)(x & (x-1));
 	y |= -y;
 	y |= -y;
 	y >>= 32-1;
 	y >>= 32-1;
@@ -480,7 +484,7 @@ u32 ceil_log2(u32 x) {
 	return cast(u32)(bit_set_count(x) - 1 - y);
 	return cast(u32)(bit_set_count(x) - 1 - y);
 }
 }
 
 
-u64 ceil_log2(u64 x) {
+gb_internal u64 ceil_log2(u64 x) {
 	i64 y = cast(i64)(x & (x-1));
 	i64 y = cast(i64)(x & (x-1));
 	y |= -y;
 	y |= -y;
 	y >>= 64-1;
 	y >>= 64-1;
@@ -493,7 +497,7 @@ u64 ceil_log2(u64 x) {
 	return cast(u64)(bit_set_count(x) - 1 - y);
 	return cast(u64)(bit_set_count(x) - 1 - y);
 }
 }
 
 
-u32 prev_pow2(u32 n) {
+gb_internal u32 prev_pow2(u32 n) {
 	if (n == 0) {
 	if (n == 0) {
 		return 0;
 		return 0;
 	}
 	}
@@ -504,7 +508,7 @@ u32 prev_pow2(u32 n) {
 	n |= n >> 16;
 	n |= n >> 16;
 	return n - (n >> 1);
 	return n - (n >> 1);
 }
 }
-i32 prev_pow2(i32 n) {
+gb_internal i32 prev_pow2(i32 n) {
 	if (n <= 0) {
 	if (n <= 0) {
 		return 0;
 		return 0;
 	}
 	}
@@ -515,7 +519,7 @@ i32 prev_pow2(i32 n) {
 	n |= n >> 16;
 	n |= n >> 16;
 	return n - (n >> 1);
 	return n - (n >> 1);
 }
 }
-i64 prev_pow2(i64 n) {
+gb_internal i64 prev_pow2(i64 n) {
 	if (n <= 0) {
 	if (n <= 0) {
 		return 0;
 		return 0;
 	}
 	}
@@ -528,7 +532,7 @@ i64 prev_pow2(i64 n) {
 	return n - (n >> 1);
 	return n - (n >> 1);
 }
 }
 
 
-u16 f32_to_f16(f32 value) {
+gb_internal u16 f32_to_f16(f32 value) {
 	union { u32 i; f32 f; } v;
 	union { u32 i; f32 f; } v;
 	i32 i, s, e, m;
 	i32 i, s, e, m;
 
 
@@ -579,7 +583,7 @@ u16 f32_to_f16(f32 value) {
 	}
 	}
 }
 }
 
 
-f32 f16_to_f32(u16 value) {
+gb_internal f32 f16_to_f32(u16 value) {
 	typedef union { u32 u; f32 f; } fp32;
 	typedef union { u32 u; f32 f; } fp32;
 	fp32 v;
 	fp32 v;
 
 
@@ -595,7 +599,7 @@ f32 f16_to_f32(u16 value) {
 	return v.f;
 	return v.f;
 }
 }
 
 
-f64 gb_sqrt(f64 x) {
+gb_internal gb_inline f64 gb_sqrt(f64 x) {
 	return sqrt(x);
 	return sqrt(x);
 }
 }
 
 
@@ -623,7 +627,7 @@ f64 gb_sqrt(f64 x) {
 
 
 #if defined(GB_SYSTEM_WINDOWS)
 #if defined(GB_SYSTEM_WINDOWS)
 
 
-wchar_t **command_line_to_wargv(wchar_t *cmd_line, int *_argc) {
+gb_internal wchar_t **command_line_to_wargv(wchar_t *cmd_line, int *_argc) {
 	u32 i, j;
 	u32 i, j;
 
 
 	u32 len = cast(u32)string16_len(cmd_line);
 	u32 len = cast(u32)string16_len(cmd_line);
@@ -706,7 +710,7 @@ enum LoadedFileError {
 	LoadedFile_COUNT,
 	LoadedFile_COUNT,
 };
 };
 
 
-LoadedFileError load_file_32(char const *fullpath, LoadedFile *memory_mapped_file, bool copy_file_contents) {
+gb_internal LoadedFileError load_file_32(char const *fullpath, LoadedFile *memory_mapped_file, bool copy_file_contents) {
 	LoadedFileError err = LoadedFile_None;
 	LoadedFileError err = LoadedFile_None;
 	
 	
 	if (!copy_file_contents) {
 	if (!copy_file_contents) {
@@ -811,7 +815,7 @@ LoadedFileError load_file_32(char const *fullpath, LoadedFile *memory_mapped_fil
 
 
 #define USE_DAMERAU_LEVENSHTEIN 1
 #define USE_DAMERAU_LEVENSHTEIN 1
 
 
-isize levenstein_distance_case_insensitive(String const &a, String const &b) {
+gb_internal isize levenstein_distance_case_insensitive(String const &a, String const &b) {
 	isize w = b.len+1;
 	isize w = b.len+1;
 	isize h = a.len+1;
 	isize h = a.len+1;
 	isize *matrix = gb_alloc_array(temporary_allocator(), isize, w*h);
 	isize *matrix = gb_alloc_array(temporary_allocator(), isize, w*h);
@@ -870,16 +874,16 @@ struct DidYouMeanAnswers {
 
 
 enum {MAX_SMALLEST_DID_YOU_MEAN_DISTANCE = 3-USE_DAMERAU_LEVENSHTEIN};
 enum {MAX_SMALLEST_DID_YOU_MEAN_DISTANCE = 3-USE_DAMERAU_LEVENSHTEIN};
 
 
-DidYouMeanAnswers did_you_mean_make(gbAllocator allocator, isize cap, String const &key) {
+gb_internal DidYouMeanAnswers did_you_mean_make(gbAllocator allocator, isize cap, String const &key) {
 	DidYouMeanAnswers d = {};
 	DidYouMeanAnswers d = {};
 	array_init(&d.distances, allocator, 0, cap);
 	array_init(&d.distances, allocator, 0, cap);
 	d.key = key;
 	d.key = key;
 	return d;
 	return d;
 }
 }
-void did_you_mean_destroy(DidYouMeanAnswers *d) {
+gb_internal void did_you_mean_destroy(DidYouMeanAnswers *d) {
 	array_free(&d->distances);
 	array_free(&d->distances);
 }
 }
-void did_you_mean_append(DidYouMeanAnswers *d, String const &target) {
+gb_internal void did_you_mean_append(DidYouMeanAnswers *d, String const &target) {
 	if (target.len == 0 || target == "_") {
 	if (target.len == 0 || target == "_") {
 		return;
 		return;
 	}
 	}
@@ -888,7 +892,7 @@ void did_you_mean_append(DidYouMeanAnswers *d, String const &target) {
 	dat.distance = levenstein_distance_case_insensitive(d->key, target);
 	dat.distance = levenstein_distance_case_insensitive(d->key, target);
 	array_add(&d->distances, dat);
 	array_add(&d->distances, dat);
 }
 }
-Slice<DistanceAndTarget> did_you_mean_results(DidYouMeanAnswers *d) {
+gb_internal Slice<DistanceAndTarget> did_you_mean_results(DidYouMeanAnswers *d) {
 	gb_sort_array(d->distances.data, d->distances.count, gb_isize_cmp(gb_offset_of(DistanceAndTarget, distance)));
 	gb_sort_array(d->distances.data, d->distances.count, gb_isize_cmp(gb_offset_of(DistanceAndTarget, distance)));
 	isize count = 0;
 	isize count = 0;
 	for (isize i = 0; i < d->distances.count; i++) {
 	for (isize i = 0; i < d->distances.count; i++) {
@@ -900,3 +904,8 @@ Slice<DistanceAndTarget> did_you_mean_results(DidYouMeanAnswers *d) {
 	}
 	}
 	return slice_array(d->distances, 0, count);
 	return slice_array(d->distances, 0, count);
 }
 }
+
+
+#if defined(GB_SYSTEM_WINDOWS)
+	#pragma warning(pop)
+#endif

+ 39 - 39
src/common_memory.cpp

@@ -1,5 +1,5 @@
 
 
-gb_inline void zero_size(void *ptr, isize len) {
+gb_internal gb_inline void zero_size(void *ptr, isize len) {
 	memset(ptr, 0, len);
 	memset(ptr, 0, len);
 }
 }
 
 
@@ -7,27 +7,27 @@ gb_inline void zero_size(void *ptr, isize len) {
 
 
 
 
 template <typename U, typename V>
 template <typename U, typename V>
-gb_inline U bit_cast(V &v) { return reinterpret_cast<U &>(v); }
+gb_internal gb_inline U bit_cast(V &v) { return reinterpret_cast<U &>(v); }
 
 
 template <typename U, typename V>
 template <typename U, typename V>
-gb_inline U const &bit_cast(V const &v) { return reinterpret_cast<U const &>(v); }
+gb_internal gb_inline U const &bit_cast(V const &v) { return reinterpret_cast<U const &>(v); }
 
 
 
 
-gb_inline i64 align_formula(i64 size, i64 align) {
+gb_internal gb_inline i64 align_formula(i64 size, i64 align) {
 	if (align > 0) {
 	if (align > 0) {
 		i64 result = size + align-1;
 		i64 result = size + align-1;
 		return result - result%align;
 		return result - result%align;
 	}
 	}
 	return size;
 	return size;
 }
 }
-gb_inline isize align_formula_isize(isize size, isize align) {
+gb_internal gb_inline isize align_formula_isize(isize size, isize align) {
 	if (align > 0) {
 	if (align > 0) {
 		isize result = size + align-1;
 		isize result = size + align-1;
 		return result - result%align;
 		return result - result%align;
 	}
 	}
 	return size;
 	return size;
 }
 }
-gb_inline void *align_formula_ptr(void *ptr, isize align) {
+gb_internal gb_inline void *align_formula_ptr(void *ptr, isize align) {
 	if (align > 0) {
 	if (align > 0) {
 		uintptr result = (cast(uintptr)ptr) + align-1;
 		uintptr result = (cast(uintptr)ptr) + align-1;
 		return (void *)(result - result%align);
 		return (void *)(result - result%align);
@@ -39,9 +39,9 @@ gb_inline void *align_formula_ptr(void *ptr, isize align) {
 gb_global BlockingMutex global_memory_block_mutex;
 gb_global BlockingMutex global_memory_block_mutex;
 gb_global BlockingMutex global_memory_allocator_mutex;
 gb_global BlockingMutex global_memory_allocator_mutex;
 
 
-void platform_virtual_memory_init(void);
+gb_internal void platform_virtual_memory_init(void);
 
 
-void virtual_memory_init(void) {
+gb_internal void virtual_memory_init(void) {
 	mutex_init(&global_memory_block_mutex);
 	mutex_init(&global_memory_block_mutex);
 	mutex_init(&global_memory_allocator_mutex);
 	mutex_init(&global_memory_allocator_mutex);
 	platform_virtual_memory_init();
 	platform_virtual_memory_init();
@@ -66,13 +66,13 @@ enum { DEFAULT_MINIMUM_BLOCK_SIZE = 8ll*1024ll*1024ll };
 
 
 gb_global isize DEFAULT_PAGE_SIZE = 4096;
 gb_global isize DEFAULT_PAGE_SIZE = 4096;
 
 
-MemoryBlock *virtual_memory_alloc(isize size);
-void virtual_memory_dealloc(MemoryBlock *block);
-void *arena_alloc(Arena *arena, isize min_size, isize alignment);
-void arena_free_all(Arena *arena);
+gb_internal MemoryBlock *virtual_memory_alloc(isize size);
+gb_internal void virtual_memory_dealloc(MemoryBlock *block);
+gb_internal void *arena_alloc(Arena *arena, isize min_size, isize alignment);
+gb_internal void arena_free_all(Arena *arena);
 
 
 
 
-isize arena_align_forward_offset(Arena *arena, isize alignment) {
+gb_internal isize arena_align_forward_offset(Arena *arena, isize alignment) {
 	isize alignment_offset = 0;
 	isize alignment_offset = 0;
 	isize ptr = cast(isize)(arena->curr_block->base + arena->curr_block->used);
 	isize ptr = cast(isize)(arena->curr_block->base + arena->curr_block->used);
 	isize mask = alignment-1;
 	isize mask = alignment-1;
@@ -82,7 +82,7 @@ isize arena_align_forward_offset(Arena *arena, isize alignment) {
 	return alignment_offset;
 	return alignment_offset;
 }
 }
 
 
-void *arena_alloc(Arena *arena, isize min_size, isize alignment) {
+gb_internal void *arena_alloc(Arena *arena, isize min_size, isize alignment) {
 	GB_ASSERT(gb_is_power_of_two(alignment));
 	GB_ASSERT(gb_is_power_of_two(alignment));
 	
 	
 	BlockingMutex *mutex = &global_memory_allocator_mutex;
 	BlockingMutex *mutex = &global_memory_allocator_mutex;
@@ -123,7 +123,7 @@ void *arena_alloc(Arena *arena, isize min_size, isize alignment) {
 	return ptr;	
 	return ptr;	
 }
 }
 
 
-void arena_free_all(Arena *arena) {
+gb_internal void arena_free_all(Arena *arena) {
 	while (arena->curr_block != nullptr) {
 	while (arena->curr_block != nullptr) {
 		MemoryBlock *free_block = arena->curr_block;
 		MemoryBlock *free_block = arena->curr_block;
 		arena->curr_block = free_block->prev;
 		arena->curr_block = free_block->prev;
@@ -142,12 +142,12 @@ struct PlatformMemoryBlock {
 gb_global std::atomic<isize> global_platform_memory_total_usage;
 gb_global std::atomic<isize> global_platform_memory_total_usage;
 gb_global PlatformMemoryBlock global_platform_memory_block_sentinel;
 gb_global PlatformMemoryBlock global_platform_memory_block_sentinel;
 
 
-PlatformMemoryBlock *platform_virtual_memory_alloc(isize total_size);
-void platform_virtual_memory_free(PlatformMemoryBlock *block);
-void platform_virtual_memory_protect(void *memory, isize size);
+gb_internal PlatformMemoryBlock *platform_virtual_memory_alloc(isize total_size);
+gb_internal void platform_virtual_memory_free(PlatformMemoryBlock *block);
+gb_internal void platform_virtual_memory_protect(void *memory, isize size);
 
 
 #if defined(GB_SYSTEM_WINDOWS)
 #if defined(GB_SYSTEM_WINDOWS)
-	void platform_virtual_memory_init(void) {
+	gb_internal void platform_virtual_memory_init(void) {
 		global_platform_memory_block_sentinel.prev = &global_platform_memory_block_sentinel;	
 		global_platform_memory_block_sentinel.prev = &global_platform_memory_block_sentinel;	
 		global_platform_memory_block_sentinel.next = &global_platform_memory_block_sentinel;
 		global_platform_memory_block_sentinel.next = &global_platform_memory_block_sentinel;
 		
 		
@@ -157,7 +157,7 @@ void platform_virtual_memory_protect(void *memory, isize size);
 		GB_ASSERT(gb_is_power_of_two(DEFAULT_PAGE_SIZE));
 		GB_ASSERT(gb_is_power_of_two(DEFAULT_PAGE_SIZE));
 	}
 	}
 
 
-	PlatformMemoryBlock *platform_virtual_memory_alloc(isize total_size) {
+	gb_internal PlatformMemoryBlock *platform_virtual_memory_alloc(isize total_size) {
 		PlatformMemoryBlock *pmblock = (PlatformMemoryBlock *)VirtualAlloc(0, total_size, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
 		PlatformMemoryBlock *pmblock = (PlatformMemoryBlock *)VirtualAlloc(0, total_size, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
 		if (pmblock == nullptr) {
 		if (pmblock == nullptr) {
 			gb_printf_err("Out of Virtual memory, oh no...\n");
 			gb_printf_err("Out of Virtual memory, oh no...\n");
@@ -165,20 +165,20 @@ void platform_virtual_memory_protect(void *memory, isize size);
 			gb_printf_err("Total Usage: %lld bytes\n", cast(long long)global_platform_memory_total_usage);
 			gb_printf_err("Total Usage: %lld bytes\n", cast(long long)global_platform_memory_total_usage);
 			GB_ASSERT_MSG(pmblock != nullptr, "Out of Virtual Memory, oh no...");
 			GB_ASSERT_MSG(pmblock != nullptr, "Out of Virtual Memory, oh no...");
 		}
 		}
-		global_platform_memory_total_usage += total_size;
+		global_platform_memory_total_usage.fetch_add(total_size);
 		return pmblock;
 		return pmblock;
 	}
 	}
-	void platform_virtual_memory_free(PlatformMemoryBlock *block) {
-		global_platform_memory_total_usage -= block->total_size;
+	gb_internal void platform_virtual_memory_free(PlatformMemoryBlock *block) {
+		global_platform_memory_total_usage.fetch_sub(block->total_size);
 		GB_ASSERT(VirtualFree(block, 0, MEM_RELEASE));
 		GB_ASSERT(VirtualFree(block, 0, MEM_RELEASE));
 	}
 	}
-	void platform_virtual_memory_protect(void *memory, isize size) {
+	gb_internal void platform_virtual_memory_protect(void *memory, isize size) {
 		DWORD old_protect = 0;
 		DWORD old_protect = 0;
 		BOOL is_protected = VirtualProtect(memory, size, PAGE_NOACCESS, &old_protect);
 		BOOL is_protected = VirtualProtect(memory, size, PAGE_NOACCESS, &old_protect);
 		GB_ASSERT(is_protected);
 		GB_ASSERT(is_protected);
 	}
 	}
 #else
 #else
-	void platform_virtual_memory_init(void) {
+	gb_internal void platform_virtual_memory_init(void) {
 		global_platform_memory_block_sentinel.prev = &global_platform_memory_block_sentinel;	
 		global_platform_memory_block_sentinel.prev = &global_platform_memory_block_sentinel;	
 		global_platform_memory_block_sentinel.next = &global_platform_memory_block_sentinel;
 		global_platform_memory_block_sentinel.next = &global_platform_memory_block_sentinel;
 		
 		
@@ -186,7 +186,7 @@ void platform_virtual_memory_protect(void *memory, isize size);
 		GB_ASSERT(gb_is_power_of_two(DEFAULT_PAGE_SIZE));
 		GB_ASSERT(gb_is_power_of_two(DEFAULT_PAGE_SIZE));
 	}
 	}
 	
 	
-	PlatformMemoryBlock *platform_virtual_memory_alloc(isize total_size) {
+	gb_internal PlatformMemoryBlock *platform_virtual_memory_alloc(isize total_size) {
 		PlatformMemoryBlock *pmblock = (PlatformMemoryBlock *)mmap(nullptr, total_size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
 		PlatformMemoryBlock *pmblock = (PlatformMemoryBlock *)mmap(nullptr, total_size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
 		if (pmblock == nullptr) {
 		if (pmblock == nullptr) {
 			gb_printf_err("Out of Virtual memory, oh no...\n");
 			gb_printf_err("Out of Virtual memory, oh no...\n");
@@ -197,18 +197,18 @@ void platform_virtual_memory_protect(void *memory, isize size);
 		global_platform_memory_total_usage += total_size;
 		global_platform_memory_total_usage += total_size;
 		return pmblock;
 		return pmblock;
 	}
 	}
-	void platform_virtual_memory_free(PlatformMemoryBlock *block) {
+	gb_internal void platform_virtual_memory_free(PlatformMemoryBlock *block) {
 		isize size = block->total_size;
 		isize size = block->total_size;
 		global_platform_memory_total_usage -= size;
 		global_platform_memory_total_usage -= size;
 		munmap(block, size);
 		munmap(block, size);
 	}
 	}
-	void platform_virtual_memory_protect(void *memory, isize size) {
+	gb_internal void platform_virtual_memory_protect(void *memory, isize size) {
 		int err = mprotect(memory, size, PROT_NONE);
 		int err = mprotect(memory, size, PROT_NONE);
 		GB_ASSERT(err == 0);
 		GB_ASSERT(err == 0);
 	}
 	}
 #endif
 #endif
 
 
-MemoryBlock *virtual_memory_alloc(isize size) {
+gb_internal MemoryBlock *virtual_memory_alloc(isize size) {
 	isize const page_size = DEFAULT_PAGE_SIZE; 
 	isize const page_size = DEFAULT_PAGE_SIZE; 
 	
 	
 	isize total_size     = size + gb_size_of(PlatformMemoryBlock);
 	isize total_size     = size + gb_size_of(PlatformMemoryBlock);
@@ -250,7 +250,7 @@ MemoryBlock *virtual_memory_alloc(isize size) {
 	return &pmblock->block;
 	return &pmblock->block;
 }
 }
 
 
-void virtual_memory_dealloc(MemoryBlock *block_to_free) {
+gb_internal void virtual_memory_dealloc(MemoryBlock *block_to_free) {
 	PlatformMemoryBlock *block = cast(PlatformMemoryBlock *)block_to_free;
 	PlatformMemoryBlock *block = cast(PlatformMemoryBlock *)block_to_free;
 	if (block != nullptr) {
 	if (block != nullptr) {
 		mutex_lock(&global_memory_block_mutex);
 		mutex_lock(&global_memory_block_mutex);
@@ -265,9 +265,9 @@ void virtual_memory_dealloc(MemoryBlock *block_to_free) {
 
 
 
 
 
 
-GB_ALLOCATOR_PROC(arena_allocator_proc);
+gb_internal GB_ALLOCATOR_PROC(arena_allocator_proc);
 
 
-gbAllocator arena_allocator(Arena *arena) {
+gb_internal gbAllocator arena_allocator(Arena *arena) {
 	gbAllocator a;
 	gbAllocator a;
 	a.proc = arena_allocator_proc;
 	a.proc = arena_allocator_proc;
 	a.data = arena;
 	a.data = arena;
@@ -275,7 +275,7 @@ gbAllocator arena_allocator(Arena *arena) {
 }
 }
 
 
 
 
-GB_ALLOCATOR_PROC(arena_allocator_proc) {
+gb_internal GB_ALLOCATOR_PROC(arena_allocator_proc) {
 	void *ptr = nullptr;
 	void *ptr = nullptr;
 	Arena *arena = cast(Arena *)allocator_data;
 	Arena *arena = cast(Arena *)allocator_data;
 	GB_ASSERT_NOT_NULL(arena);
 	GB_ASSERT_NOT_NULL(arena);
@@ -307,11 +307,11 @@ GB_ALLOCATOR_PROC(arena_allocator_proc) {
 
 
 
 
 gb_global gb_thread_local Arena permanent_arena = {nullptr, DEFAULT_MINIMUM_BLOCK_SIZE, true};
 gb_global gb_thread_local Arena permanent_arena = {nullptr, DEFAULT_MINIMUM_BLOCK_SIZE, true};
-gbAllocator permanent_allocator() {
+gb_internal gbAllocator permanent_allocator() {
 	return arena_allocator(&permanent_arena);
 	return arena_allocator(&permanent_arena);
 }
 }
 
 
-gbAllocator temporary_allocator() {
+gb_internal gbAllocator temporary_allocator() {
 	return permanent_allocator();
 	return permanent_allocator();
 }
 }
 
 
@@ -320,9 +320,9 @@ gbAllocator temporary_allocator() {
 
 
 
 
 
 
-GB_ALLOCATOR_PROC(heap_allocator_proc);
+gb_internal GB_ALLOCATOR_PROC(heap_allocator_proc);
 
 
-gbAllocator heap_allocator(void) {
+gb_internal gbAllocator heap_allocator(void) {
 	gbAllocator a;
 	gbAllocator a;
 	a.proc = heap_allocator_proc;
 	a.proc = heap_allocator_proc;
 	a.data = nullptr;
 	a.data = nullptr;
@@ -330,7 +330,7 @@ gbAllocator heap_allocator(void) {
 }
 }
 
 
 
 
-GB_ALLOCATOR_PROC(heap_allocator_proc) {
+gb_internal GB_ALLOCATOR_PROC(heap_allocator_proc) {
 	void *ptr = nullptr;
 	void *ptr = nullptr;
 	gb_unused(allocator_data);
 	gb_unused(allocator_data);
 	gb_unused(old_size);
 	gb_unused(old_size);
@@ -460,7 +460,7 @@ GB_ALLOCATOR_PROC(heap_allocator_proc) {
 
 
 
 
 template <typename T>
 template <typename T>
-void resize_array_raw(T **array, gbAllocator const &a, isize old_count, isize new_count) {
+gb_internal void resize_array_raw(T **array, gbAllocator const &a, isize old_count, isize new_count) {
 	GB_ASSERT(new_count >= 0);
 	GB_ASSERT(new_count >= 0);
 	if (new_count == 0) {
 	if (new_count == 0) {
 		gb_free(a, *array);
 		gb_free(a, *array);

+ 13 - 23
src/docs.cpp

@@ -28,7 +28,7 @@ gb_global char const *print_entity_names[Entity_Count] = {
 };
 };
 
 
 
 
-GB_COMPARE_PROC(cmp_entities_for_printing) {
+gb_internal GB_COMPARE_PROC(cmp_entities_for_printing) {
 	GB_ASSERT(a != nullptr);
 	GB_ASSERT(a != nullptr);
 	GB_ASSERT(b != nullptr);
 	GB_ASSERT(b != nullptr);
 	Entity *x = *cast(Entity **)a;
 	Entity *x = *cast(Entity **)a;
@@ -56,7 +56,7 @@ GB_COMPARE_PROC(cmp_entities_for_printing) {
 	return res;
 	return res;
 }
 }
 
 
-GB_COMPARE_PROC(cmp_ast_package_by_name) {
+gb_internal GB_COMPARE_PROC(cmp_ast_package_by_name) {
 	GB_ASSERT(a != nullptr);
 	GB_ASSERT(a != nullptr);
 	GB_ASSERT(b != nullptr);
 	GB_ASSERT(b != nullptr);
 	AstPackage *x = *cast(AstPackage **)a;
 	AstPackage *x = *cast(AstPackage **)a;
@@ -67,7 +67,7 @@ GB_COMPARE_PROC(cmp_ast_package_by_name) {
 #include "docs_format.cpp"
 #include "docs_format.cpp"
 #include "docs_writer.cpp"
 #include "docs_writer.cpp"
 
 
-void print_doc_line(i32 indent, String const &data) {
+gb_internal void print_doc_line(i32 indent, String const &data) {
 	while (indent --> 0) {
 	while (indent --> 0) {
 		gb_printf("\t");
 		gb_printf("\t");
 	}
 	}
@@ -75,7 +75,7 @@ void print_doc_line(i32 indent, String const &data) {
 	gb_printf("\n");
 	gb_printf("\n");
 }
 }
 
 
-void print_doc_line(i32 indent, char const *fmt, ...) {
+gb_internal void print_doc_line(i32 indent, char const *fmt, ...) {
 	while (indent --> 0) {
 	while (indent --> 0) {
 		gb_printf("\t");
 		gb_printf("\t");
 	}
 	}
@@ -85,16 +85,7 @@ void print_doc_line(i32 indent, char const *fmt, ...) {
 	va_end(va);
 	va_end(va);
 	gb_printf("\n");
 	gb_printf("\n");
 }
 }
-void print_doc_line_no_newline(i32 indent, char const *fmt, ...) {
-	while (indent --> 0) {
-		gb_printf("\t");
-	}
-	va_list va;
-	va_start(va, fmt);
-	gb_printf_va(fmt, va);
-	va_end(va);
-}
-void print_doc_line_no_newline(i32 indent, String const &data) {
+gb_internal void print_doc_line_no_newline(i32 indent, String const &data) {
 	while (indent --> 0) {
 	while (indent --> 0) {
 		gb_printf("\t");
 		gb_printf("\t");
 	}
 	}
@@ -102,7 +93,7 @@ void print_doc_line_no_newline(i32 indent, String const &data) {
 }
 }
 
 
 
 
-bool print_doc_comment_group_string(i32 indent, CommentGroup *g) {
+gb_internal bool print_doc_comment_group_string(i32 indent, CommentGroup *g) {
 	if (g == nullptr) {
 	if (g == nullptr) {
 		return false;
 		return false;
 	}
 	}
@@ -191,7 +182,7 @@ bool print_doc_comment_group_string(i32 indent, CommentGroup *g) {
 
 
 
 
 
 
-void print_doc_expr(Ast *expr) {
+gb_internal void print_doc_expr(Ast *expr) {
 	gbString s = nullptr;
 	gbString s = nullptr;
 	if (build_context.cmd_doc_flags & CmdDocFlag_Short) {
 	if (build_context.cmd_doc_flags & CmdDocFlag_Short) {
 		s = expr_to_string_shorthand(expr);
 		s = expr_to_string_shorthand(expr);
@@ -202,8 +193,7 @@ void print_doc_expr(Ast *expr) {
 	gb_string_free(s);
 	gb_string_free(s);
 }
 }
 
 
-
-void print_doc_package(CheckerInfo *info, AstPackage *pkg) {
+gb_internal void print_doc_package(CheckerInfo *info, AstPackage *pkg) {
 	if (pkg == nullptr) {
 	if (pkg == nullptr) {
 		return;
 		return;
 	}
 	}
@@ -222,8 +212,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:
@@ -320,7 +310,7 @@ void print_doc_package(CheckerInfo *info, AstPackage *pkg) {
 
 
 }
 }
 
 
-void generate_documentation(Checker *c) {
+gb_internal void generate_documentation(Checker *c) {
 	CheckerInfo *info = &c->info;
 	CheckerInfo *info = &c->info;
 
 
 	if (build_context.cmd_doc_flags & CmdDocFlag_DocFormat) {
 	if (build_context.cmd_doc_flags & CmdDocFlag_DocFormat) {
@@ -359,8 +349,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 {

+ 2 - 2
src/docs_format.cpp

@@ -27,14 +27,14 @@ struct OdinDocHeaderBase {
 };
 };
 
 
 template <typename T>
 template <typename T>
-Slice<T> from_array(OdinDocHeaderBase *base, OdinDocArray<T> const &a) {
+gb_internal Slice<T> from_array(OdinDocHeaderBase *base, OdinDocArray<T> const &a) {
 	Slice<T> s = {};
 	Slice<T> s = {};
 	s.data  = cast(T *)(cast(uintptr)base + cast(uintptr)a.offset);
 	s.data  = cast(T *)(cast(uintptr)base + cast(uintptr)a.offset);
 	s.count = cast(isize)a.length;
 	s.count = cast(isize)a.length;
 	return s;
 	return s;
 }
 }
 
 
-String from_string(OdinDocHeaderBase *base, OdinDocString const &s) {
+gb_internal String from_string(OdinDocHeaderBase *base, OdinDocString const &s) {
 	String str = {};
 	String str = {};
 	str.text = cast(u8 *)(cast(uintptr)base + cast(uintptr)s.offset);
 	str.text = cast(u8 *)(cast(uintptr)base + cast(uintptr)s.offset);
 	str.len  = cast(isize)s.length;
 	str.len  = cast(isize)s.length;

+ 51 - 53
src/docs_writer.cpp

@@ -11,7 +11,7 @@ enum OdinDocWriterState {
 	OdinDocWriterState_Writing,
 	OdinDocWriterState_Writing,
 };
 };
 
 
-char const* OdinDocWriterState_strings[] {
+gb_global char const* OdinDocWriterState_strings[] {
 	"preparing",
 	"preparing",
 	"writing  ",
 	"writing  ",
 };
 };
@@ -40,17 +40,17 @@ struct OdinDocWriter {
 	OdinDocWriterItemTracker<u8> blob;
 	OdinDocWriterItemTracker<u8> blob;
 };
 };
 
 
-OdinDocEntityIndex odin_doc_add_entity(OdinDocWriter *w, Entity *e);
-OdinDocTypeIndex odin_doc_type(OdinDocWriter *w, Type *type);
+gb_internal OdinDocEntityIndex odin_doc_add_entity(OdinDocWriter *w, Entity *e);
+gb_internal OdinDocTypeIndex odin_doc_type(OdinDocWriter *w, Type *type);
 
 
 template <typename T>
 template <typename T>
-void odin_doc_writer_item_tracker_init(OdinDocWriterItemTracker<T> *t, isize size) {
+gb_internal void odin_doc_writer_item_tracker_init(OdinDocWriterItemTracker<T> *t, isize size) {
 	t->len = size;
 	t->len = size;
 	t->cap = size;
 	t->cap = size;
 }
 }
 
 
 
 
-void odin_doc_writer_prepare(OdinDocWriter *w) {
+gb_internal void odin_doc_writer_prepare(OdinDocWriter *w) {
 	w->state = OdinDocWriterState_Preparing;
 	w->state = OdinDocWriterState_Preparing;
 
 
 	gbAllocator a = heap_allocator();
 	gbAllocator a = heap_allocator();
@@ -70,7 +70,7 @@ void odin_doc_writer_prepare(OdinDocWriter *w) {
 }
 }
 
 
 
 
-void odin_doc_writer_destroy(OdinDocWriter *w) {
+gb_internal void odin_doc_writer_destroy(OdinDocWriter *w) {
 	gb_free(heap_allocator(), w->data);
 	gb_free(heap_allocator(), w->data);
 
 
 	string_map_destroy(&w->string_cache);
 	string_map_destroy(&w->string_cache);
@@ -83,7 +83,7 @@ void odin_doc_writer_destroy(OdinDocWriter *w) {
 
 
 
 
 template <typename T>
 template <typename T>
-void odin_doc_writer_tracker_size(isize *offset, OdinDocWriterItemTracker<T> *t, isize alignment=1) {
+gb_internal void odin_doc_writer_tracker_size(isize *offset, OdinDocWriterItemTracker<T> *t, isize alignment=1) {
 	isize size = t->cap*gb_size_of(T);
 	isize size = t->cap*gb_size_of(T);
 	isize align = gb_max(gb_align_of(T), alignment);
 	isize align = gb_max(gb_align_of(T), alignment);
 	*offset = align_formula_isize(*offset, align);
 	*offset = align_formula_isize(*offset, align);
@@ -91,7 +91,7 @@ void odin_doc_writer_tracker_size(isize *offset, OdinDocWriterItemTracker<T> *t,
 	*offset += size;
 	*offset += size;
 }
 }
 
 
-isize odin_doc_writer_calc_total_size(OdinDocWriter *w) {
+gb_internal isize odin_doc_writer_calc_total_size(OdinDocWriter *w) {
 	isize total_size = gb_size_of(OdinDocHeader);
 	isize total_size = gb_size_of(OdinDocHeader);
 	odin_doc_writer_tracker_size(&total_size, &w->files);
 	odin_doc_writer_tracker_size(&total_size, &w->files);
 	odin_doc_writer_tracker_size(&total_size, &w->pkgs);
 	odin_doc_writer_tracker_size(&total_size, &w->pkgs);
@@ -102,7 +102,7 @@ isize odin_doc_writer_calc_total_size(OdinDocWriter *w) {
 	return total_size;
 	return total_size;
 }
 }
 
 
-void odin_doc_writer_start_writing(OdinDocWriter *w) {
+gb_internal void odin_doc_writer_start_writing(OdinDocWriter *w) {
 	w->state = OdinDocWriterState_Writing;
 	w->state = OdinDocWriterState_Writing;
 
 
 	string_map_clear(&w->string_cache);
 	string_map_clear(&w->string_cache);
@@ -118,7 +118,7 @@ void odin_doc_writer_start_writing(OdinDocWriter *w) {
 	w->header = cast(OdinDocHeader *)w->data;
 	w->header = cast(OdinDocHeader *)w->data;
 }
 }
 
 
-u32 hash_data_after_header(OdinDocHeaderBase *base, void *data, isize data_len) {
+gb_internal u32 hash_data_after_header(OdinDocHeaderBase *base, void *data, isize data_len) {
 	u8 *start = cast(u8 *)data;
 	u8 *start = cast(u8 *)data;
 	u8 *end = start + base->total_size;
 	u8 *end = start + base->total_size;
 	start += base->header_size;
 	start += base->header_size;
@@ -132,13 +132,13 @@ u32 hash_data_after_header(OdinDocHeaderBase *base, void *data, isize data_len)
 
 
 
 
 template <typename T>
 template <typename T>
-void odin_doc_writer_assign_tracker(OdinDocArray<T> *array, OdinDocWriterItemTracker<T> const &t) {
+gb_internal void odin_doc_writer_assign_tracker(OdinDocArray<T> *array, OdinDocWriterItemTracker<T> const &t) {
 	array->offset = cast(u32)t.offset;
 	array->offset = cast(u32)t.offset;
 	array->length = cast(u32)t.len;
 	array->length = cast(u32)t.len;
 }
 }
 
 
 
 
-void odin_doc_writer_end_writing(OdinDocWriter *w) {
+gb_internal void odin_doc_writer_end_writing(OdinDocWriter *w) {
 	OdinDocHeader *h = w->header;
 	OdinDocHeader *h = w->header;
 
 
 	gb_memmove(h->base.magic, OdinDocHeader_MagicString, gb_strlen(OdinDocHeader_MagicString));
 	gb_memmove(h->base.magic, OdinDocHeader_MagicString, gb_strlen(OdinDocHeader_MagicString));
@@ -156,7 +156,7 @@ void odin_doc_writer_end_writing(OdinDocWriter *w) {
 }
 }
 
 
 template <typename T>
 template <typename T>
-u32 odin_doc_write_item(OdinDocWriter *w, OdinDocWriterItemTracker<T> *t, T const *item, T **dst=nullptr) {
+gb_internal u32 odin_doc_write_item(OdinDocWriter *w, OdinDocWriterItemTracker<T> *t, T const *item, T **dst=nullptr) {
 	if (w->state == OdinDocWriterState_Preparing) {
 	if (w->state == OdinDocWriterState_Preparing) {
 		t->cap += 1;
 		t->cap += 1;
 		if (dst) *dst = nullptr;
 		if (dst) *dst = nullptr;
@@ -175,7 +175,7 @@ u32 odin_doc_write_item(OdinDocWriter *w, OdinDocWriterItemTracker<T> *t, T cons
 }
 }
 
 
 template <typename T>
 template <typename T>
-T *odin_doc_get_item(OdinDocWriter *w, OdinDocWriterItemTracker<T> *t, u32 index) {
+gb_internal T *odin_doc_get_item(OdinDocWriter *w, OdinDocWriterItemTracker<T> *t, u32 index) {
 	if (w->state != OdinDocWriterState_Writing) {
 	if (w->state != OdinDocWriterState_Writing) {
 		return nullptr;
 		return nullptr;
 	}
 	}
@@ -184,7 +184,7 @@ T *odin_doc_get_item(OdinDocWriter *w, OdinDocWriterItemTracker<T> *t, u32 index
 	return cast(T *)data;
 	return cast(T *)data;
 }
 }
 
 
-OdinDocString odin_doc_write_string_without_cache(OdinDocWriter *w, String const &str) {
+gb_internal OdinDocString odin_doc_write_string_without_cache(OdinDocWriter *w, String const &str) {
 	OdinDocString res = {};
 	OdinDocString res = {};
 
 
 	if (w->state == OdinDocWriterState_Preparing) {
 	if (w->state == OdinDocWriterState_Preparing) {
@@ -204,7 +204,7 @@ OdinDocString odin_doc_write_string_without_cache(OdinDocWriter *w, String const
 	return res;
 	return res;
 }
 }
 
 
-OdinDocString odin_doc_write_string(OdinDocWriter *w, String const &str) {
+gb_internal OdinDocString odin_doc_write_string(OdinDocWriter *w, String const &str) {
 	OdinDocString *c = string_map_get(&w->string_cache, str);
 	OdinDocString *c = string_map_get(&w->string_cache, str);
 	if (c != nullptr) {
 	if (c != nullptr) {
 		if (w->state == OdinDocWriterState_Writing) {
 		if (w->state == OdinDocWriterState_Writing) {
@@ -223,7 +223,7 @@ OdinDocString odin_doc_write_string(OdinDocWriter *w, String const &str) {
 
 
 
 
 template <typename T>
 template <typename T>
-OdinDocArray<T> odin_write_slice(OdinDocWriter *w, T *data, isize len) {
+gb_internal OdinDocArray<T> odin_write_slice(OdinDocWriter *w, T *data, isize len) {
 	GB_ASSERT(gb_align_of(T) <= 4);
 	GB_ASSERT(gb_align_of(T) <= 4);
 	if (len <= 0) {
 	if (len <= 0) {
 		return {0, 0};
 		return {0, 0};
@@ -249,12 +249,12 @@ OdinDocArray<T> odin_write_slice(OdinDocWriter *w, T *data, isize len) {
 
 
 
 
 template <typename T>
 template <typename T>
-OdinDocArray<T> odin_write_item_as_slice(OdinDocWriter *w, T data) {
+gb_internal OdinDocArray<T> odin_write_item_as_slice(OdinDocWriter *w, T data) {
 	return odin_write_slice(w, &data, 1);
 	return odin_write_slice(w, &data, 1);
 }
 }
 
 
 
 
-OdinDocPosition odin_doc_token_pos_cast(OdinDocWriter *w, TokenPos const &pos) {
+gb_internal OdinDocPosition odin_doc_token_pos_cast(OdinDocWriter *w, TokenPos const &pos) {
 	OdinDocFileIndex file_index = 0;
 	OdinDocFileIndex file_index = 0;
 	if (pos.file_id != 0) {
 	if (pos.file_id != 0) {
 		AstFile *file = global_files[pos.file_id];
 		AstFile *file = global_files[pos.file_id];
@@ -273,7 +273,7 @@ OdinDocPosition odin_doc_token_pos_cast(OdinDocWriter *w, TokenPos const &pos) {
 	return doc_pos;
 	return doc_pos;
 }
 }
 
 
-bool odin_doc_append_comment_group_string(Array<u8> *buf, CommentGroup *g) {
+gb_internal bool odin_doc_append_comment_group_string(Array<u8> *buf, CommentGroup *g) {
 	if (g == nullptr) {
 	if (g == nullptr) {
 		return false;
 		return false;
 	}
 	}
@@ -361,7 +361,7 @@ bool odin_doc_append_comment_group_string(Array<u8> *buf, CommentGroup *g) {
 	return false;
 	return false;
 }
 }
 
 
-OdinDocString odin_doc_pkg_doc_string(OdinDocWriter *w, AstPackage *pkg) {
+gb_internal OdinDocString odin_doc_pkg_doc_string(OdinDocWriter *w, AstPackage *pkg) {
 	if (pkg == nullptr) {
 	if (pkg == nullptr) {
 		return {};
 		return {};
 	}
 	}
@@ -378,7 +378,7 @@ OdinDocString odin_doc_pkg_doc_string(OdinDocWriter *w, AstPackage *pkg) {
 	return odin_doc_write_string_without_cache(w, make_string(buf.data, buf.count));
 	return odin_doc_write_string_without_cache(w, make_string(buf.data, buf.count));
 }
 }
 
 
-OdinDocString odin_doc_comment_group_string(OdinDocWriter *w, CommentGroup *g) {
+gb_internal OdinDocString odin_doc_comment_group_string(OdinDocWriter *w, CommentGroup *g) {
 	if (g == nullptr) {
 	if (g == nullptr) {
 		return {};
 		return {};
 	}
 	}
@@ -389,7 +389,7 @@ OdinDocString odin_doc_comment_group_string(OdinDocWriter *w, CommentGroup *g) {
 	return odin_doc_write_string_without_cache(w, make_string(buf.data, buf.count));
 	return odin_doc_write_string_without_cache(w, make_string(buf.data, buf.count));
 }
 }
 
 
-OdinDocString odin_doc_expr_string(OdinDocWriter *w, Ast *expr) {
+gb_internal OdinDocString odin_doc_expr_string(OdinDocWriter *w, Ast *expr) {
 	if (expr == nullptr) {
 	if (expr == nullptr) {
 		return {};
 		return {};
 	}
 	}
@@ -402,7 +402,7 @@ OdinDocString odin_doc_expr_string(OdinDocWriter *w, Ast *expr) {
 	return odin_doc_write_string(w, make_string(cast(u8 *)s, gb_string_length(s)));
 	return odin_doc_write_string(w, make_string(cast(u8 *)s, gb_string_length(s)));
 }
 }
 
 
-OdinDocArray<OdinDocAttribute> odin_doc_attributes(OdinDocWriter *w, Array<Ast *> const &attributes) {
+gb_internal OdinDocArray<OdinDocAttribute> odin_doc_attributes(OdinDocWriter *w, Array<Ast *> const &attributes) {
 	isize count = 0;
 	isize count = 0;
 	for_array(i, attributes) {
 	for_array(i, attributes) {
 		Ast *attr = attributes[i];
 		Ast *attr = attributes[i];
@@ -448,7 +448,7 @@ OdinDocArray<OdinDocAttribute> odin_doc_attributes(OdinDocWriter *w, Array<Ast *
 	return odin_write_slice(w, attribs.data, attribs.count);
 	return odin_write_slice(w, attribs.data, attribs.count);
 }
 }
 
 
-OdinDocArray<OdinDocString> odin_doc_where_clauses(OdinDocWriter *w, Slice<Ast *> const &where_clauses) {
+gb_internal OdinDocArray<OdinDocString> odin_doc_where_clauses(OdinDocWriter *w, Slice<Ast *> const &where_clauses) {
 	if (where_clauses.count == 0) {
 	if (where_clauses.count == 0) {
 		return {};
 		return {};
 	}
 	}
@@ -462,17 +462,17 @@ OdinDocArray<OdinDocString> odin_doc_where_clauses(OdinDocWriter *w, Slice<Ast *
 	return odin_write_slice(w, clauses.data, clauses.count);
 	return odin_write_slice(w, clauses.data, clauses.count);
 }
 }
 
 
-OdinDocArray<OdinDocTypeIndex> odin_doc_type_as_slice(OdinDocWriter *w, Type *type) {
+gb_internal OdinDocArray<OdinDocTypeIndex> odin_doc_type_as_slice(OdinDocWriter *w, Type *type) {
 	OdinDocTypeIndex index = odin_doc_type(w, type);
 	OdinDocTypeIndex index = odin_doc_type(w, type);
 	return odin_write_item_as_slice(w, index);
 	return odin_write_item_as_slice(w, index);
 }
 }
 
 
-OdinDocArray<OdinDocEntityIndex> odin_doc_add_entity_as_slice(OdinDocWriter *w, Entity *e) {
+gb_internal OdinDocArray<OdinDocEntityIndex> odin_doc_add_entity_as_slice(OdinDocWriter *w, Entity *e) {
 	OdinDocEntityIndex index = odin_doc_add_entity(w, e);
 	OdinDocEntityIndex index = odin_doc_add_entity(w, e);
 	return odin_write_item_as_slice(w, index);
 	return odin_write_item_as_slice(w, index);
 }
 }
 
 
-OdinDocTypeIndex odin_doc_type(OdinDocWriter *w, Type *type) {
+gb_internal OdinDocTypeIndex odin_doc_type(OdinDocWriter *w, Type *type) {
 	if (type == nullptr) {
 	if (type == nullptr) {
 		return 0;
 		return 0;
 	}
 	}
@@ -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;
 		}
 		}
@@ -750,7 +750,7 @@ OdinDocTypeIndex odin_doc_type(OdinDocWriter *w, Type *type) {
 	}
 	}
 	return type_index;
 	return type_index;
 }
 }
-OdinDocEntityIndex odin_doc_add_entity(OdinDocWriter *w, Entity *e) {
+gb_internal OdinDocEntityIndex odin_doc_add_entity(OdinDocWriter *w, Entity *e) {
 	if (e == nullptr) {
 	if (e == nullptr) {
 		return 0;
 		return 0;
 	}
 	}
@@ -911,26 +911,24 @@ OdinDocEntityIndex odin_doc_add_entity(OdinDocWriter *w, Entity *e) {
 	return doc_entity_index;
 	return doc_entity_index;
 }
 }
 
 
-void odin_doc_update_entities(OdinDocWriter *w) {
+gb_internal 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);
@@ -968,7 +966,7 @@ void odin_doc_update_entities(OdinDocWriter *w) {
 
 
 
 
 
 
-OdinDocArray<OdinDocScopeEntry> odin_doc_add_pkg_entries(OdinDocWriter *w, AstPackage *pkg) {
+gb_internal OdinDocArray<OdinDocScopeEntry> odin_doc_add_pkg_entries(OdinDocWriter *w, AstPackage *pkg) {
 	if (pkg->scope == nullptr) {
 	if (pkg->scope == nullptr) {
 		return {};
 		return {};
 	}
 	}
@@ -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 &element : pkg->scope->elements) {
+		String name = element.key.string;
+		Entity *e = element.value;
 		switch (e->kind) {
 		switch (e->kind) {
 		case Entity_Invalid:
 		case Entity_Invalid:
 		case Entity_Nil:
 		case Entity_Nil:
@@ -1018,11 +1016,11 @@ OdinDocArray<OdinDocScopeEntry> odin_doc_add_pkg_entries(OdinDocWriter *w, AstPa
 }
 }
 
 
 
 
-void odin_doc_write_docs(OdinDocWriter *w) {
+gb_internal 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 {
@@ -1093,7 +1091,7 @@ void odin_doc_write_docs(OdinDocWriter *w) {
 }
 }
 
 
 
 
-void odin_doc_write_to_file(OdinDocWriter *w, char const *filename) {
+gb_internal void odin_doc_write_to_file(OdinDocWriter *w, char const *filename) {
 	gbFile f = {};
 	gbFile f = {};
 	gbFileError err = gb_file_open_mode(&f, gbFileMode_Write, filename);
 	gbFileError err = gb_file_open_mode(&f, gbFileMode_Write, filename);
 	if (err != gbFileError_None) {
 	if (err != gbFileError_None) {
@@ -1108,7 +1106,7 @@ void odin_doc_write_to_file(OdinDocWriter *w, char const *filename) {
 	}
 	}
 }
 }
 
 
-void odin_doc_write(CheckerInfo *info, char const *filename) {
+gb_internal void odin_doc_write(CheckerInfo *info, char const *filename) {
 	OdinDocWriter w_ = {};
 	OdinDocWriter w_ = {};
 	OdinDocWriter *w = &w_;
 	OdinDocWriter *w = &w_;
 	defer (odin_doc_writer_destroy(w));
 	defer (odin_doc_writer_destroy(w));

+ 25 - 33
src/entity.cpp

@@ -26,7 +26,7 @@ enum EntityKind {
 	Entity_Count,
 	Entity_Count,
 };
 };
 
 
-String const entity_strings[] = {
+gb_global String const entity_strings[] = {
 #define ENTITY_KIND(k) {cast(u8 *)#k, gb_size_of(#k)-1},
 #define ENTITY_KIND(k) {cast(u8 *)#k, gb_size_of(#k)-1},
 	ENTITY_KINDS
 	ENTITY_KINDS
 #undef ENTITY_KIND
 #undef ENTITY_KIND
@@ -116,7 +116,7 @@ struct ParameterValue {
 	};
 	};
 };
 };
 
 
-bool has_parameter_value(ParameterValue const &param_value) {
+gb_internal gb_inline bool has_parameter_value(ParameterValue const &param_value) {
 	if (param_value.kind != ParameterValue_Invalid) {
 	if (param_value.kind != ParameterValue_Invalid) {
 		return true;
 		return true;
 	}
 	}
@@ -151,7 +151,7 @@ struct TypeNameObjCMetadata {
 	Array<TypeNameObjCMetadataEntry> value_entries;
 	Array<TypeNameObjCMetadataEntry> value_entries;
 };
 };
 
 
-TypeNameObjCMetadata *create_type_name_obj_c_metadata() {
+gb_internal TypeNameObjCMetadata *create_type_name_obj_c_metadata() {
 	TypeNameObjCMetadata *md = gb_alloc_item(permanent_allocator(), TypeNameObjCMetadata);
 	TypeNameObjCMetadata *md = gb_alloc_item(permanent_allocator(), TypeNameObjCMetadata);
 	md->mutex = gb_alloc_item(permanent_allocator(), BlockingMutex);
 	md->mutex = gb_alloc_item(permanent_allocator(), BlockingMutex);
 	mutex_init(md->mutex);
 	mutex_init(md->mutex);
@@ -266,7 +266,7 @@ struct Entity {
 	};
 	};
 };
 };
 
 
-bool is_entity_kind_exported(EntityKind kind, bool allow_builtin = false) {
+gb_internal bool is_entity_kind_exported(EntityKind kind, bool allow_builtin = false) {
 	switch (kind) {
 	switch (kind) {
 	case Entity_Builtin:
 	case Entity_Builtin:
 		return allow_builtin;
 		return allow_builtin;
@@ -278,7 +278,7 @@ bool is_entity_kind_exported(EntityKind kind, bool allow_builtin = false) {
 	return true;
 	return true;
 }
 }
 
 
-bool is_entity_exported(Entity *e, bool allow_builtin = false) {
+gb_internal bool is_entity_exported(Entity *e, bool allow_builtin = false) {
 	// TODO(bill): Determine the actual exportation rules for imports of entities
 	// TODO(bill): Determine the actual exportation rules for imports of entities
 	GB_ASSERT(e != nullptr);
 	GB_ASSERT(e != nullptr);
 	if (!is_entity_kind_exported(e->kind, allow_builtin)) {
 	if (!is_entity_kind_exported(e->kind, allow_builtin)) {
@@ -300,7 +300,7 @@ bool is_entity_exported(Entity *e, bool allow_builtin = false) {
 	return true;
 	return true;
 }
 }
 
 
-bool entity_has_deferred_procedure(Entity *e) {
+gb_internal bool entity_has_deferred_procedure(Entity *e) {
 	GB_ASSERT(e != nullptr);
 	GB_ASSERT(e != nullptr);
 	if (e->kind == Entity_Procedure) {
 	if (e->kind == Entity_Procedure) {
 		return e->Procedure.deferred_procedure.entity != nullptr;
 		return e->Procedure.deferred_procedure.entity != nullptr;
@@ -311,7 +311,7 @@ bool entity_has_deferred_procedure(Entity *e) {
 
 
 gb_global std::atomic<u64> global_entity_id;
 gb_global std::atomic<u64> global_entity_id;
 
 
-Entity *alloc_entity(EntityKind kind, Scope *scope, Token token, Type *type) {
+gb_internal Entity *alloc_entity(EntityKind kind, Scope *scope, Token token, Type *type) {
 	gbAllocator a = permanent_allocator();
 	gbAllocator a = permanent_allocator();
 	Entity *entity = gb_alloc_item(a, Entity);
 	Entity *entity = gb_alloc_item(a, Entity);
 	entity->kind   = kind;
 	entity->kind   = kind;
@@ -323,13 +323,13 @@ Entity *alloc_entity(EntityKind kind, Scope *scope, Token token, Type *type) {
 	return entity;
 	return entity;
 }
 }
 
 
-Entity *alloc_entity_variable(Scope *scope, Token token, Type *type, EntityState state = EntityState_Unresolved) {
+gb_internal Entity *alloc_entity_variable(Scope *scope, Token token, Type *type, EntityState state = EntityState_Unresolved) {
 	Entity *entity = alloc_entity(Entity_Variable, scope, token, type);
 	Entity *entity = alloc_entity(Entity_Variable, scope, token, type);
 	entity->state = state;
 	entity->state = state;
 	return entity;
 	return entity;
 }
 }
 
 
-Entity *alloc_entity_using_variable(Entity *parent, Token token, Type *type, Ast *using_expr) {
+gb_internal Entity *alloc_entity_using_variable(Entity *parent, Token token, Type *type, Ast *using_expr) {
 	GB_ASSERT(parent != nullptr);
 	GB_ASSERT(parent != nullptr);
 	token.pos = parent->token.pos;
 	token.pos = parent->token.pos;
 	Entity *entity = alloc_entity(Entity_Variable, parent->scope, token, type);
 	Entity *entity = alloc_entity(Entity_Variable, parent->scope, token, type);
@@ -343,19 +343,19 @@ Entity *alloc_entity_using_variable(Entity *parent, Token token, Type *type, Ast
 }
 }
 
 
 
 
-Entity *alloc_entity_constant(Scope *scope, Token token, Type *type, ExactValue value) {
+gb_internal Entity *alloc_entity_constant(Scope *scope, Token token, Type *type, ExactValue value) {
 	Entity *entity = alloc_entity(Entity_Constant, scope, token, type);
 	Entity *entity = alloc_entity(Entity_Constant, scope, token, type);
 	entity->Constant.value = value;
 	entity->Constant.value = value;
 	return entity;
 	return entity;
 }
 }
 
 
-Entity *alloc_entity_type_name(Scope *scope, Token token, Type *type, EntityState state = EntityState_Unresolved) {
+gb_internal Entity *alloc_entity_type_name(Scope *scope, Token token, Type *type, EntityState state = EntityState_Unresolved) {
 	Entity *entity = alloc_entity(Entity_TypeName, scope, token, type);
 	Entity *entity = alloc_entity(Entity_TypeName, scope, token, type);
 	entity->state = state;
 	entity->state = state;
 	return entity;
 	return entity;
 }
 }
 
 
-Entity *alloc_entity_param(Scope *scope, Token token, Type *type, bool is_using, bool is_value) {
+gb_internal Entity *alloc_entity_param(Scope *scope, Token token, Type *type, bool is_using, bool is_value) {
 	Entity *entity = alloc_entity_variable(scope, token, type);
 	Entity *entity = alloc_entity_variable(scope, token, type);
 	entity->flags |= EntityFlag_Used;
 	entity->flags |= EntityFlag_Used;
 	entity->flags |= EntityFlag_Param;
 	entity->flags |= EntityFlag_Param;
@@ -366,7 +366,7 @@ Entity *alloc_entity_param(Scope *scope, Token token, Type *type, bool is_using,
 }
 }
 
 
 
 
-Entity *alloc_entity_const_param(Scope *scope, Token token, Type *type, ExactValue value, bool poly_const) {
+gb_internal Entity *alloc_entity_const_param(Scope *scope, Token token, Type *type, ExactValue value, bool poly_const) {
 	Entity *entity = alloc_entity_constant(scope, token, type, value);
 	Entity *entity = alloc_entity_constant(scope, token, type, value);
 	entity->flags |= EntityFlag_Used;
 	entity->flags |= EntityFlag_Used;
 	if (poly_const) entity->flags |= EntityFlag_PolyConst;
 	if (poly_const) entity->flags |= EntityFlag_PolyConst;
@@ -375,7 +375,7 @@ Entity *alloc_entity_const_param(Scope *scope, Token token, Type *type, ExactVal
 }
 }
 
 
 
 
-Entity *alloc_entity_field(Scope *scope, Token token, Type *type, bool is_using, i32 field_index, EntityState state = EntityState_Unresolved) {
+gb_internal Entity *alloc_entity_field(Scope *scope, Token token, Type *type, bool is_using, i32 field_index, EntityState state = EntityState_Unresolved) {
 	Entity *entity = alloc_entity_variable(scope, token, type);
 	Entity *entity = alloc_entity_variable(scope, token, type);
 	entity->Variable.field_index = field_index;
 	entity->Variable.field_index = field_index;
 	if (is_using) entity->flags |= EntityFlag_Using;
 	if (is_using) entity->flags |= EntityFlag_Using;
@@ -384,7 +384,7 @@ Entity *alloc_entity_field(Scope *scope, Token token, Type *type, bool is_using,
 	return entity;
 	return entity;
 }
 }
 
 
-Entity *alloc_entity_array_elem(Scope *scope, Token token, Type *type, i32 field_index) {
+gb_internal Entity *alloc_entity_array_elem(Scope *scope, Token token, Type *type, i32 field_index) {
 	Entity *entity = alloc_entity_variable(scope, token, type);
 	Entity *entity = alloc_entity_variable(scope, token, type);
 	entity->Variable.field_index = field_index;
 	entity->Variable.field_index = field_index;
 	entity->flags |= EntityFlag_Field;
 	entity->flags |= EntityFlag_Field;
@@ -393,26 +393,18 @@ Entity *alloc_entity_array_elem(Scope *scope, Token token, Type *type, i32 field
 	return entity;
 	return entity;
 }
 }
 
 
-Entity *alloc_entity_procedure(Scope *scope, Token token, Type *signature_type, u64 tags) {
+gb_internal Entity *alloc_entity_procedure(Scope *scope, Token token, Type *signature_type, u64 tags) {
 	Entity *entity = alloc_entity(Entity_Procedure, scope, token, signature_type);
 	Entity *entity = alloc_entity(Entity_Procedure, scope, token, signature_type);
 	entity->Procedure.tags = tags;
 	entity->Procedure.tags = tags;
 	return entity;
 	return entity;
 }
 }
 
 
-Entity *alloc_entity_proc_group(Scope *scope, Token token, Type *type) {
+gb_internal Entity *alloc_entity_proc_group(Scope *scope, Token token, Type *type) {
 	Entity *entity = alloc_entity(Entity_ProcGroup, scope, token, type);
 	Entity *entity = alloc_entity(Entity_ProcGroup, scope, token, type);
 	return entity;
 	return entity;
 }
 }
 
 
-
-Entity *alloc_entity_builtin(Scope *scope, Token token, Type *type, i32 id) {
-	Entity *entity = alloc_entity(Entity_Builtin, scope, token, type);
-	entity->Builtin.id = id;
-	entity->state = EntityState_Resolved;
-	return entity;
-}
-
-Entity *alloc_entity_import_name(Scope *scope, Token token, Type *type,
+gb_internal Entity *alloc_entity_import_name(Scope *scope, Token token, Type *type,
                                  String path, String name, Scope *import_scope) {
                                  String path, String name, Scope *import_scope) {
 	Entity *entity = alloc_entity(Entity_ImportName, scope, token, type);
 	Entity *entity = alloc_entity(Entity_ImportName, scope, token, type);
 	entity->ImportName.path = path;
 	entity->ImportName.path = path;
@@ -422,7 +414,7 @@ Entity *alloc_entity_import_name(Scope *scope, Token token, Type *type,
 	return entity;
 	return entity;
 }
 }
 
 
-Entity *alloc_entity_library_name(Scope *scope, Token token, Type *type,
+gb_internal Entity *alloc_entity_library_name(Scope *scope, Token token, Type *type,
                                   Slice<String> paths, String name) {
                                   Slice<String> paths, String name) {
 	Entity *entity = alloc_entity(Entity_LibraryName, scope, token, type);
 	Entity *entity = alloc_entity(Entity_LibraryName, scope, token, type);
 	entity->LibraryName.paths = paths;
 	entity->LibraryName.paths = paths;
@@ -435,12 +427,12 @@ Entity *alloc_entity_library_name(Scope *scope, Token token, Type *type,
 
 
 
 
 
 
-Entity *alloc_entity_nil(String name, Type *type) {
+gb_internal Entity *alloc_entity_nil(String name, Type *type) {
 	Entity *entity = alloc_entity(Entity_Nil, nullptr, make_token_ident(name), type);
 	Entity *entity = alloc_entity(Entity_Nil, nullptr, make_token_ident(name), type);
 	return entity;
 	return entity;
 }
 }
 
 
-Entity *alloc_entity_label(Scope *scope, Token token, Type *type, Ast *node, Ast *parent) {
+gb_internal Entity *alloc_entity_label(Scope *scope, Token token, Type *type, Ast *node, Ast *parent) {
 	Entity *entity = alloc_entity(Entity_Label, scope, token, type);
 	Entity *entity = alloc_entity(Entity_Label, scope, token, type);
 	entity->Label.node = node;
 	entity->Label.node = node;
 	entity->Label.parent = parent;
 	entity->Label.parent = parent;
@@ -448,15 +440,15 @@ Entity *alloc_entity_label(Scope *scope, Token token, Type *type, Ast *node, Ast
 	return entity;
 	return entity;
 }
 }
 
 
-Entity *alloc_entity_dummy_variable(Scope *scope, Token token) {
+gb_internal Entity *alloc_entity_dummy_variable(Scope *scope, Token token) {
 	token.string = str_lit("_");
 	token.string = str_lit("_");
 	return alloc_entity_variable(scope, token, nullptr);
 	return alloc_entity_variable(scope, token, nullptr);
 }
 }
 
 
 
 
-Entity *entity_from_expr(Ast *expr);
+gb_internal Entity *entity_from_expr(Ast *expr);
 
 
-Entity *strip_entity_wrapping(Entity *e) {
+gb_internal Entity *strip_entity_wrapping(Entity *e) {
 	if (e == nullptr) {
 	if (e == nullptr) {
 		return nullptr;
 		return nullptr;
 	}
 	}
@@ -469,7 +461,7 @@ Entity *strip_entity_wrapping(Entity *e) {
 	return e;
 	return e;
 }
 }
 
 
-Entity *strip_entity_wrapping(Ast *expr) {
+gb_internal Entity *strip_entity_wrapping(Ast *expr) {
 	Entity *e = entity_from_expr(expr);
 	Entity *e = entity_from_expr(expr);
 	return strip_entity_wrapping(e);
 	return strip_entity_wrapping(e);
 }
 }

+ 31 - 31
src/error.cpp

@@ -17,11 +17,11 @@ gb_global ErrorCollector global_error_collector;
 #define MAX_ERROR_COLLECTOR_COUNT (36)
 #define MAX_ERROR_COLLECTOR_COUNT (36)
 
 
 
 
-bool any_errors(void) {
+gb_internal bool any_errors(void) {
 	return global_error_collector.count.load() != 0;
 	return global_error_collector.count.load() != 0;
 }
 }
 
 
-void init_global_error_collector(void) {
+gb_internal void init_global_error_collector(void) {
 	mutex_init(&global_error_collector.mutex);
 	mutex_init(&global_error_collector.mutex);
 	mutex_init(&global_error_collector.block_mutex);
 	mutex_init(&global_error_collector.block_mutex);
 	mutex_init(&global_error_collector.error_out_mutex);
 	mutex_init(&global_error_collector.error_out_mutex);
@@ -35,9 +35,9 @@ void init_global_error_collector(void) {
 
 
 // temporary
 // temporary
 // defined in build_settings.cpp
 // defined in build_settings.cpp
-char *token_pos_to_string(TokenPos const &pos);
+gb_internal char *token_pos_to_string(TokenPos const &pos);
 
 
-bool set_file_path_string(i32 index, String const &path) {
+gb_internal bool set_file_path_string(i32 index, String const &path) {
 	bool ok = false;
 	bool ok = false;
 	GB_ASSERT(index >= 0);
 	GB_ASSERT(index >= 0);
 	mutex_lock(&global_error_collector.string_mutex);
 	mutex_lock(&global_error_collector.string_mutex);
@@ -55,7 +55,7 @@ bool set_file_path_string(i32 index, String const &path) {
 	return ok;
 	return ok;
 }
 }
 
 
-bool thread_safe_set_ast_file_from_id(i32 index, AstFile *file) {
+gb_internal bool thread_safe_set_ast_file_from_id(i32 index, AstFile *file) {
 	bool ok = false;
 	bool ok = false;
 	GB_ASSERT(index >= 0);
 	GB_ASSERT(index >= 0);
 	mutex_lock(&global_error_collector.string_mutex);
 	mutex_lock(&global_error_collector.string_mutex);
@@ -73,7 +73,7 @@ bool thread_safe_set_ast_file_from_id(i32 index, AstFile *file) {
 	return ok;
 	return ok;
 }
 }
 
 
-String get_file_path_string(i32 index) {
+gb_internal String get_file_path_string(i32 index) {
 	GB_ASSERT(index >= 0);
 	GB_ASSERT(index >= 0);
 	mutex_lock(&global_error_collector.string_mutex);
 	mutex_lock(&global_error_collector.string_mutex);
 
 
@@ -86,7 +86,7 @@ String get_file_path_string(i32 index) {
 	return path;
 	return path;
 }
 }
 
 
-AstFile *thread_safe_get_ast_file_from_id(i32 index) {
+gb_internal AstFile *thread_safe_get_ast_file_from_id(i32 index) {
 	GB_ASSERT(index >= 0);
 	GB_ASSERT(index >= 0);
 	mutex_lock(&global_error_collector.string_mutex);
 	mutex_lock(&global_error_collector.string_mutex);
 
 
@@ -101,12 +101,12 @@ AstFile *thread_safe_get_ast_file_from_id(i32 index) {
 
 
 
 
 
 
-void begin_error_block(void) {
+gb_internal void begin_error_block(void) {
 	mutex_lock(&global_error_collector.block_mutex);
 	mutex_lock(&global_error_collector.block_mutex);
 	global_error_collector.in_block.store(true);
 	global_error_collector.in_block.store(true);
 }
 }
 
 
-void end_error_block(void) {
+gb_internal void end_error_block(void) {
 	if (global_error_collector.error_buffer.count > 0) {
 	if (global_error_collector.error_buffer.count > 0) {
 		isize n = global_error_collector.error_buffer.count;
 		isize n = global_error_collector.error_buffer.count;
 		u8 *text = gb_alloc_array(permanent_allocator(), u8, n+1);
 		u8 *text = gb_alloc_array(permanent_allocator(), u8, n+1);
@@ -127,7 +127,7 @@ void end_error_block(void) {
 #define ERROR_OUT_PROC(name) void name(char const *fmt, va_list va)
 #define ERROR_OUT_PROC(name) void name(char const *fmt, va_list va)
 typedef ERROR_OUT_PROC(ErrorOutProc);
 typedef ERROR_OUT_PROC(ErrorOutProc);
 
 
-ERROR_OUT_PROC(default_error_out_va) {
+gb_internal ERROR_OUT_PROC(default_error_out_va) {
 	gbFile *f = gb_file_get_standard(gbFileStandard_Error);
 	gbFile *f = gb_file_get_standard(gbFileStandard_Error);
 
 
 	char buf[4096] = {};
 	char buf[4096] = {};
@@ -154,15 +154,15 @@ ERROR_OUT_PROC(default_error_out_va) {
 }
 }
 
 
 
 
-ErrorOutProc *error_out_va = default_error_out_va;
+gb_global ErrorOutProc *error_out_va = default_error_out_va;
 
 
 // NOTE: defined in build_settings.cpp
 // NOTE: defined in build_settings.cpp
-bool global_warnings_as_errors(void);
-bool global_ignore_warnings(void);
-bool show_error_line(void);
-gbString get_file_line_as_string(TokenPos const &pos, i32 *offset);
+gb_internal bool global_warnings_as_errors(void);
+gb_internal bool global_ignore_warnings(void);
+gb_internal bool show_error_line(void);
+gb_internal gbString get_file_line_as_string(TokenPos const &pos, i32 *offset);
 
 
-void error_out(char const *fmt, ...) {
+gb_internal void error_out(char const *fmt, ...) {
 	va_list va;
 	va_list va;
 	va_start(va, fmt);
 	va_start(va, fmt);
 	error_out_va(fmt, va);
 	error_out_va(fmt, va);
@@ -170,7 +170,7 @@ void error_out(char const *fmt, ...) {
 }
 }
 
 
 
 
-bool show_error_on_line(TokenPos const &pos, TokenPos end) {
+gb_internal bool show_error_on_line(TokenPos const &pos, TokenPos end) {
 	if (!show_error_line()) {
 	if (!show_error_line()) {
 		return false;
 		return false;
 	}
 	}
@@ -237,7 +237,7 @@ bool show_error_on_line(TokenPos const &pos, TokenPos end) {
 	return false;
 	return false;
 }
 }
 
 
-void error_va(TokenPos const &pos, TokenPos end, char const *fmt, va_list va) {
+gb_internal void error_va(TokenPos const &pos, TokenPos end, char const *fmt, va_list va) {
 	global_error_collector.count.fetch_add(1);
 	global_error_collector.count.fetch_add(1);
 
 
 	mutex_lock(&global_error_collector.mutex);
 	mutex_lock(&global_error_collector.mutex);
@@ -257,7 +257,7 @@ void error_va(TokenPos const &pos, TokenPos end, char const *fmt, va_list va) {
 	}
 	}
 }
 }
 
 
-void warning_va(TokenPos const &pos, TokenPos end, char const *fmt, va_list va) {
+gb_internal void warning_va(TokenPos const &pos, TokenPos end, char const *fmt, va_list va) {
 	if (global_warnings_as_errors()) {
 	if (global_warnings_as_errors()) {
 		error_va(pos, end, fmt, va);
 		error_va(pos, end, fmt, va);
 		return;
 		return;
@@ -280,11 +280,11 @@ void warning_va(TokenPos const &pos, TokenPos end, char const *fmt, va_list va)
 }
 }
 
 
 
 
-void error_line_va(char const *fmt, va_list va) {
+gb_internal void error_line_va(char const *fmt, va_list va) {
 	error_out_va(fmt, va);
 	error_out_va(fmt, va);
 }
 }
 
 
-void error_no_newline_va(TokenPos const &pos, char const *fmt, va_list va) {
+gb_internal void error_no_newline_va(TokenPos const &pos, char const *fmt, va_list va) {
 	mutex_lock(&global_error_collector.mutex);
 	mutex_lock(&global_error_collector.mutex);
 	global_error_collector.count++;
 	global_error_collector.count++;
 	// NOTE(bill): Duplicate error, skip it
 	// NOTE(bill): Duplicate error, skip it
@@ -303,7 +303,7 @@ void error_no_newline_va(TokenPos const &pos, char const *fmt, va_list va) {
 }
 }
 
 
 
 
-void syntax_error_va(TokenPos const &pos, TokenPos end, char const *fmt, va_list va) {
+gb_internal void syntax_error_va(TokenPos const &pos, TokenPos end, char const *fmt, va_list va) {
 	mutex_lock(&global_error_collector.mutex);
 	mutex_lock(&global_error_collector.mutex);
 	global_error_collector.count++;
 	global_error_collector.count++;
 	// NOTE(bill): Duplicate error, skip it
 	// NOTE(bill): Duplicate error, skip it
@@ -323,7 +323,7 @@ void syntax_error_va(TokenPos const &pos, TokenPos end, char const *fmt, va_list
 	}
 	}
 }
 }
 
 
-void syntax_warning_va(TokenPos const &pos, TokenPos end, char const *fmt, va_list va) {
+gb_internal void syntax_warning_va(TokenPos const &pos, TokenPos end, char const *fmt, va_list va) {
 	if (global_warnings_as_errors()) {
 	if (global_warnings_as_errors()) {
 		syntax_error_va(pos, end, fmt, va);
 		syntax_error_va(pos, end, fmt, va);
 		return;
 		return;
@@ -347,21 +347,21 @@ void syntax_warning_va(TokenPos const &pos, TokenPos end, char const *fmt, va_li
 
 
 
 
 
 
-void warning(Token const &token, char const *fmt, ...) {
+gb_internal void warning(Token const &token, char const *fmt, ...) {
 	va_list va;
 	va_list va;
 	va_start(va, fmt);
 	va_start(va, fmt);
 	warning_va(token.pos, {}, fmt, va);
 	warning_va(token.pos, {}, fmt, va);
 	va_end(va);
 	va_end(va);
 }
 }
 
 
-void error(Token const &token, char const *fmt, ...) {
+gb_internal void error(Token const &token, char const *fmt, ...) {
 	va_list va;
 	va_list va;
 	va_start(va, fmt);
 	va_start(va, fmt);
 	error_va(token.pos, {}, fmt, va);
 	error_va(token.pos, {}, fmt, va);
 	va_end(va);
 	va_end(va);
 }
 }
 
 
-void error(TokenPos pos, char const *fmt, ...) {
+gb_internal void error(TokenPos pos, char const *fmt, ...) {
 	va_list va;
 	va_list va;
 	va_start(va, fmt);
 	va_start(va, fmt);
 	Token token = {};
 	Token token = {};
@@ -370,7 +370,7 @@ void error(TokenPos pos, char const *fmt, ...) {
 	va_end(va);
 	va_end(va);
 }
 }
 
 
-void error_line(char const *fmt, ...) {
+gb_internal void error_line(char const *fmt, ...) {
 	va_list va;
 	va_list va;
 	va_start(va, fmt);
 	va_start(va, fmt);
 	error_line_va(fmt, va);
 	error_line_va(fmt, va);
@@ -378,21 +378,21 @@ void error_line(char const *fmt, ...) {
 }
 }
 
 
 
 
-void syntax_error(Token const &token, char const *fmt, ...) {
+gb_internal void syntax_error(Token const &token, char const *fmt, ...) {
 	va_list va;
 	va_list va;
 	va_start(va, fmt);
 	va_start(va, fmt);
 	syntax_error_va(token.pos, {}, fmt, va);
 	syntax_error_va(token.pos, {}, fmt, va);
 	va_end(va);
 	va_end(va);
 }
 }
 
 
-void syntax_error(TokenPos pos, char const *fmt, ...) {
+gb_internal void syntax_error(TokenPos pos, char const *fmt, ...) {
 	va_list va;
 	va_list va;
 	va_start(va, fmt);
 	va_start(va, fmt);
 	syntax_error_va(pos, {}, fmt, va);
 	syntax_error_va(pos, {}, fmt, va);
 	va_end(va);
 	va_end(va);
 }
 }
 
 
-void syntax_warning(Token const &token, char const *fmt, ...) {
+gb_internal void syntax_warning(Token const &token, char const *fmt, ...) {
 	va_list va;
 	va_list va;
 	va_start(va, fmt);
 	va_start(va, fmt);
 	syntax_warning_va(token.pos, {}, fmt, va);
 	syntax_warning_va(token.pos, {}, fmt, va);
@@ -400,7 +400,7 @@ void syntax_warning(Token const &token, char const *fmt, ...) {
 }
 }
 
 
 
 
-void compiler_error(char const *fmt, ...) {
+gb_internal void compiler_error(char const *fmt, ...) {
 	va_list va;
 	va_list va;
 
 
 	va_start(va, fmt);
 	va_start(va, fmt);

+ 84 - 94
src/exact_value.cpp

@@ -6,7 +6,7 @@ struct Ast;
 struct HashKey;
 struct HashKey;
 struct Type;
 struct Type;
 struct Entity;
 struct Entity;
-bool are_types_identical(Type *x, Type *y);
+gb_internal bool are_types_identical(Type *x, Type *y);
 
 
 struct Complex128 {
 struct Complex128 {
 	f64 real, imag;
 	f64 real, imag;
@@ -15,16 +15,6 @@ struct Quaternion256 {
 	f64 imag, jmag, kmag, real;
 	f64 imag, jmag, kmag, real;
 };
 };
 
 
-Quaternion256 quaternion256_inverse(Quaternion256 x) {
-	f64 invmag2 = 1.0 / (x.real*x.real + x.imag*x.imag + x.jmag*x.jmag + x.kmag*x.kmag);
-	x.real = +x.real * invmag2;
-	x.imag = -x.imag * invmag2;
-	x.jmag = -x.jmag * invmag2;
-	x.kmag = -x.kmag * invmag2;
-	return x;
-}
-
-
 enum ExactValueKind {
 enum ExactValueKind {
 	ExactValue_Invalid    = 0,
 	ExactValue_Invalid    = 0,
 
 
@@ -60,7 +50,7 @@ struct ExactValue {
 
 
 gb_global ExactValue const empty_exact_value = {};
 gb_global ExactValue const empty_exact_value = {};
 
 
-uintptr hash_exact_value(ExactValue v) {
+gb_internal uintptr hash_exact_value(ExactValue v) {
 	mutex_lock(&hash_exact_value_mutex);
 	mutex_lock(&hash_exact_value_mutex);
 	defer (mutex_unlock(&hash_exact_value_mutex));
 	defer (mutex_unlock(&hash_exact_value_mutex));
 	
 	
@@ -97,44 +87,44 @@ uintptr hash_exact_value(ExactValue v) {
 }
 }
 
 
 
 
-ExactValue exact_value_compound(Ast *node) {
+gb_internal ExactValue exact_value_compound(Ast *node) {
 	ExactValue result = {ExactValue_Compound};
 	ExactValue result = {ExactValue_Compound};
 	result.value_compound = node;
 	result.value_compound = node;
 	return result;
 	return result;
 }
 }
 
 
-ExactValue exact_value_bool(bool b) {
+gb_internal ExactValue exact_value_bool(bool b) {
 	ExactValue result = {ExactValue_Bool};
 	ExactValue result = {ExactValue_Bool};
 	result.value_bool = (b != 0);
 	result.value_bool = (b != 0);
 	return result;
 	return result;
 }
 }
 
 
-ExactValue exact_value_string(String string) {
+gb_internal ExactValue exact_value_string(String string) {
 	// TODO(bill): Allow for numbers with underscores in them
 	// TODO(bill): Allow for numbers with underscores in them
 	ExactValue result = {ExactValue_String};
 	ExactValue result = {ExactValue_String};
 	result.value_string = string;
 	result.value_string = string;
 	return result;
 	return result;
 }
 }
 
 
-ExactValue exact_value_i64(i64 i) {
+gb_internal ExactValue exact_value_i64(i64 i) {
 	ExactValue result = {ExactValue_Integer};
 	ExactValue result = {ExactValue_Integer};
 	big_int_from_i64(&result.value_integer, i);
 	big_int_from_i64(&result.value_integer, i);
 	return result;
 	return result;
 }
 }
 
 
-ExactValue exact_value_u64(u64 i) {
+gb_internal ExactValue exact_value_u64(u64 i) {
 	ExactValue result = {ExactValue_Integer};
 	ExactValue result = {ExactValue_Integer};
 	big_int_from_u64(&result.value_integer, i);
 	big_int_from_u64(&result.value_integer, i);
 	return result;
 	return result;
 }
 }
 
 
-ExactValue exact_value_float(f64 f) {
+gb_internal ExactValue exact_value_float(f64 f) {
 	ExactValue result = {ExactValue_Float};
 	ExactValue result = {ExactValue_Float};
 	result.value_float = f;
 	result.value_float = f;
 	return result;
 	return result;
 }
 }
 
 
-ExactValue exact_value_complex(f64 real, f64 imag) {
+gb_internal ExactValue exact_value_complex(f64 real, f64 imag) {
 	ExactValue result = {ExactValue_Complex};
 	ExactValue result = {ExactValue_Complex};
 	result.value_complex = gb_alloc_item(permanent_allocator(), Complex128);
 	result.value_complex = gb_alloc_item(permanent_allocator(), Complex128);
 	result.value_complex->real = real;
 	result.value_complex->real = real;
@@ -142,7 +132,7 @@ ExactValue exact_value_complex(f64 real, f64 imag) {
 	return result;
 	return result;
 }
 }
 
 
-ExactValue exact_value_quaternion(f64 real, f64 imag, f64 jmag, f64 kmag) {
+gb_internal ExactValue exact_value_quaternion(f64 real, f64 imag, f64 jmag, f64 kmag) {
 	ExactValue result = {ExactValue_Quaternion};
 	ExactValue result = {ExactValue_Quaternion};
 	result.value_quaternion = gb_alloc_item(permanent_allocator(), Quaternion256);
 	result.value_quaternion = gb_alloc_item(permanent_allocator(), Quaternion256);
 	result.value_quaternion->real = real;
 	result.value_quaternion->real = real;
@@ -152,27 +142,27 @@ ExactValue exact_value_quaternion(f64 real, f64 imag, f64 jmag, f64 kmag) {
 	return result;
 	return result;
 }
 }
 
 
-ExactValue exact_value_pointer(i64 ptr) {
+gb_internal ExactValue exact_value_pointer(i64 ptr) {
 	ExactValue result = {ExactValue_Pointer};
 	ExactValue result = {ExactValue_Pointer};
 	result.value_pointer = ptr;
 	result.value_pointer = ptr;
 	return result;
 	return result;
 }
 }
 
 
-ExactValue exact_value_procedure(Ast *node) {
+gb_internal ExactValue exact_value_procedure(Ast *node) {
 	ExactValue result = {ExactValue_Procedure};
 	ExactValue result = {ExactValue_Procedure};
 	result.value_procedure = node;
 	result.value_procedure = node;
 	return result;
 	return result;
 }
 }
 
 
 
 
-ExactValue exact_value_typeid(Type *type) {
+gb_internal ExactValue exact_value_typeid(Type *type) {
 	ExactValue result = {ExactValue_Typeid};
 	ExactValue result = {ExactValue_Typeid};
 	result.value_typeid = type;
 	result.value_typeid = type;
 	return result;
 	return result;
 }
 }
 
 
 
 
-ExactValue exact_value_integer_from_string(String const &string) {
+gb_internal ExactValue exact_value_integer_from_string(String const &string) {
 	ExactValue result = {ExactValue_Integer};
 	ExactValue result = {ExactValue_Integer};
 	bool success;
 	bool success;
 	big_int_from_string(&result.value_integer, string, &success);
 	big_int_from_string(&result.value_integer, string, &success);
@@ -184,7 +174,7 @@ ExactValue exact_value_integer_from_string(String const &string) {
 
 
 
 
 
 
-f64 float_from_string(String string) {
+gb_internal f64 float_from_string(String string) {
 	isize i = 0;
 	isize i = 0;
 	u8 *str = string.text;
 	u8 *str = string.text;
 	isize len = string.len;
 	isize len = string.len;
@@ -262,7 +252,7 @@ f64 float_from_string(String string) {
 	return sign * (frac ? (value / scale) : (value * scale));
 	return sign * (frac ? (value / scale) : (value * scale));
 }
 }
 
 
-ExactValue exact_value_float_from_string(String string) {
+gb_internal ExactValue exact_value_float_from_string(String string) {
 	if (string.len > 2 && string[0] == '0' && string[1] == 'h') {
 	if (string.len > 2 && string[0] == '0' && string[1] == 'h') {
 
 
 		isize digit_count = 0;
 		isize digit_count = 0;
@@ -298,7 +288,7 @@ ExactValue exact_value_float_from_string(String string) {
 }
 }
 
 
 
 
-ExactValue exact_value_from_basic_literal(TokenKind kind, String const &string) {
+gb_internal ExactValue exact_value_from_basic_literal(TokenKind kind, String const &string) {
 	switch (kind) {
 	switch (kind) {
 	case Token_String:  return exact_value_string(string);
 	case Token_String:  return exact_value_string(string);
 	case Token_Integer: return exact_value_integer_from_string(string);
 	case Token_Integer: return exact_value_integer_from_string(string);
@@ -330,7 +320,7 @@ ExactValue exact_value_from_basic_literal(TokenKind kind, String const &string)
 	return result;
 	return result;
 }
 }
 
 
-ExactValue exact_value_to_integer(ExactValue v) {
+gb_internal ExactValue exact_value_to_integer(ExactValue v) {
 	switch (v.kind) {
 	switch (v.kind) {
 	case ExactValue_Bool: {
 	case ExactValue_Bool: {
 		i64 i = 0;
 		i64 i = 0;
@@ -357,7 +347,7 @@ ExactValue exact_value_to_integer(ExactValue v) {
 	return r;
 	return r;
 }
 }
 
 
-ExactValue exact_value_to_float(ExactValue v) {
+gb_internal ExactValue exact_value_to_float(ExactValue v) {
 	switch (v.kind) {
 	switch (v.kind) {
 	case ExactValue_Integer:
 	case ExactValue_Integer:
 		return exact_value_float(big_int_to_f64(&v.value_integer));
 		return exact_value_float(big_int_to_f64(&v.value_integer));
@@ -368,7 +358,7 @@ ExactValue exact_value_to_float(ExactValue v) {
 	return r;
 	return r;
 }
 }
 
 
-ExactValue exact_value_to_complex(ExactValue v) {
+gb_internal ExactValue exact_value_to_complex(ExactValue v) {
 	switch (v.kind) {
 	switch (v.kind) {
 	case ExactValue_Integer:
 	case ExactValue_Integer:
 		return exact_value_complex(big_int_to_f64(&v.value_integer), 0);
 		return exact_value_complex(big_int_to_f64(&v.value_integer), 0);
@@ -383,7 +373,7 @@ ExactValue exact_value_to_complex(ExactValue v) {
 	v.value_complex = gb_alloc_item(permanent_allocator(), Complex128);
 	v.value_complex = gb_alloc_item(permanent_allocator(), Complex128);
 	return r;
 	return r;
 }
 }
-ExactValue exact_value_to_quaternion(ExactValue v) {
+gb_internal ExactValue exact_value_to_quaternion(ExactValue v) {
 	switch (v.kind) {
 	switch (v.kind) {
 	case ExactValue_Integer:
 	case ExactValue_Integer:
 		return exact_value_quaternion(big_int_to_f64(&v.value_integer), 0, 0, 0);
 		return exact_value_quaternion(big_int_to_f64(&v.value_integer), 0, 0, 0);
@@ -399,7 +389,7 @@ ExactValue exact_value_to_quaternion(ExactValue v) {
 	return r;
 	return r;
 }
 }
 
 
-ExactValue exact_value_real(ExactValue v) {
+gb_internal ExactValue exact_value_real(ExactValue v) {
 	switch (v.kind) {
 	switch (v.kind) {
 	case ExactValue_Integer:
 	case ExactValue_Integer:
 	case ExactValue_Float:
 	case ExactValue_Float:
@@ -413,7 +403,7 @@ ExactValue exact_value_real(ExactValue v) {
 	return r;
 	return r;
 }
 }
 
 
-ExactValue exact_value_imag(ExactValue v) {
+gb_internal ExactValue exact_value_imag(ExactValue v) {
 	switch (v.kind) {
 	switch (v.kind) {
 	case ExactValue_Integer:
 	case ExactValue_Integer:
 	case ExactValue_Float:
 	case ExactValue_Float:
@@ -427,7 +417,7 @@ ExactValue exact_value_imag(ExactValue v) {
 	return r;
 	return r;
 }
 }
 
 
-ExactValue exact_value_jmag(ExactValue v) {
+gb_internal ExactValue exact_value_jmag(ExactValue v) {
 	switch (v.kind) {
 	switch (v.kind) {
 	case ExactValue_Integer:
 	case ExactValue_Integer:
 	case ExactValue_Float:
 	case ExactValue_Float:
@@ -440,7 +430,7 @@ ExactValue exact_value_jmag(ExactValue v) {
 	return r;
 	return r;
 }
 }
 
 
-ExactValue exact_value_kmag(ExactValue v) {
+gb_internal ExactValue exact_value_kmag(ExactValue v) {
 	switch (v.kind) {
 	switch (v.kind) {
 	case ExactValue_Integer:
 	case ExactValue_Integer:
 	case ExactValue_Float:
 	case ExactValue_Float:
@@ -453,60 +443,60 @@ ExactValue exact_value_kmag(ExactValue v) {
 	return r;
 	return r;
 }
 }
 
 
-ExactValue exact_value_make_imag(ExactValue v) {
-	switch (v.kind) {
-	case ExactValue_Integer:
-		return exact_value_complex(0, exact_value_to_float(v).value_float);
-	case ExactValue_Float:
-		return exact_value_complex(0, v.value_float);
-	default:
-		GB_PANIC("Expected an integer or float type for 'exact_value_make_imag'");
-	}
-	ExactValue r = {ExactValue_Invalid};
-	return r;
-}
-
-ExactValue exact_value_make_jmag(ExactValue v) {
-	switch (v.kind) {
-	case ExactValue_Integer:
-		return exact_value_quaternion(0, 0, exact_value_to_float(v).value_float, 0);
-	case ExactValue_Float:
-		return exact_value_quaternion(0, 0, v.value_float, 0);
-	default:
-		GB_PANIC("Expected an integer or float type for 'exact_value_make_imag'");
-	}
-	ExactValue r = {ExactValue_Invalid};
-	return r;
-}
-
-ExactValue exact_value_make_kmag(ExactValue v) {
-	switch (v.kind) {
-	case ExactValue_Integer:
-		return exact_value_quaternion(0, 0, 0, exact_value_to_float(v).value_float);
-	case ExactValue_Float:
-		return exact_value_quaternion(0, 0, 0, v.value_float);
-	default:
-		GB_PANIC("Expected an integer or float type for 'exact_value_make_imag'");
-	}
-	ExactValue r = {ExactValue_Invalid};
-	return r;
-}
-
-i64 exact_value_to_i64(ExactValue v) {
+// gb_internal ExactValue exact_value_make_imag(ExactValue v) {
+// 	switch (v.kind) {
+// 	case ExactValue_Integer:
+// 		return exact_value_complex(0, exact_value_to_float(v).value_float);
+// 	case ExactValue_Float:
+// 		return exact_value_complex(0, v.value_float);
+// 	default:
+// 		GB_PANIC("Expected an integer or float type for 'exact_value_make_imag'");
+// 	}
+// 	ExactValue r = {ExactValue_Invalid};
+// 	return r;
+// }
+
+// gb_internal ExactValue exact_value_make_jmag(ExactValue v) {
+// 	switch (v.kind) {
+// 	case ExactValue_Integer:
+// 		return exact_value_quaternion(0, 0, exact_value_to_float(v).value_float, 0);
+// 	case ExactValue_Float:
+// 		return exact_value_quaternion(0, 0, v.value_float, 0);
+// 	default:
+// 		GB_PANIC("Expected an integer or float type for 'exact_value_make_jmag'");
+// 	}
+// 	ExactValue r = {ExactValue_Invalid};
+// 	return r;
+// }
+
+// gb_internal ExactValue exact_value_make_kmag(ExactValue v) {
+// 	switch (v.kind) {
+// 	case ExactValue_Integer:
+// 		return exact_value_quaternion(0, 0, 0, exact_value_to_float(v).value_float);
+// 	case ExactValue_Float:
+// 		return exact_value_quaternion(0, 0, 0, v.value_float);
+// 	default:
+// 		GB_PANIC("Expected an integer or float type for 'exact_value_make_kmag'");
+// 	}
+// 	ExactValue r = {ExactValue_Invalid};
+// 	return r;
+// }
+
+gb_internal i64 exact_value_to_i64(ExactValue v) {
 	v = exact_value_to_integer(v);
 	v = exact_value_to_integer(v);
 	if (v.kind == ExactValue_Integer) {
 	if (v.kind == ExactValue_Integer) {
 		return big_int_to_i64(&v.value_integer);
 		return big_int_to_i64(&v.value_integer);
 	}
 	}
 	return 0;
 	return 0;
 }
 }
-u64 exact_value_to_u64(ExactValue v) {
+gb_internal u64 exact_value_to_u64(ExactValue v) {
 	v = exact_value_to_integer(v);
 	v = exact_value_to_integer(v);
 	if (v.kind == ExactValue_Integer) {
 	if (v.kind == ExactValue_Integer) {
 		return big_int_to_u64(&v.value_integer);
 		return big_int_to_u64(&v.value_integer);
 	}
 	}
 	return 0;
 	return 0;
 }
 }
-f64 exact_value_to_f64(ExactValue v) {
+gb_internal f64 exact_value_to_f64(ExactValue v) {
 	v = exact_value_to_float(v);
 	v = exact_value_to_float(v);
 	if (v.kind == ExactValue_Float) {
 	if (v.kind == ExactValue_Float) {
 		return v.value_float;
 		return v.value_float;
@@ -519,7 +509,7 @@ f64 exact_value_to_f64(ExactValue v) {
 
 
 
 
 
 
-ExactValue exact_unary_operator_value(TokenKind op, ExactValue v, i32 precision, bool is_unsigned) {
+gb_internal ExactValue exact_unary_operator_value(TokenKind op, ExactValue v, i32 precision, bool is_unsigned) {
 	switch (op) {
 	switch (op) {
 	case Token_Add:	{
 	case Token_Add:	{
 		switch (v.kind) {
 		switch (v.kind) {
@@ -596,7 +586,7 @@ failure:
 }
 }
 
 
 // NOTE(bill): Make sure things are evaluated in correct order
 // NOTE(bill): Make sure things are evaluated in correct order
-i32 exact_value_order(ExactValue const &v) {
+gb_internal i32 exact_value_order(ExactValue const &v) {
 	switch (v.kind) {
 	switch (v.kind) {
 	case ExactValue_Invalid:
 	case ExactValue_Invalid:
 	case ExactValue_Compound:
 	case ExactValue_Compound:
@@ -623,7 +613,7 @@ i32 exact_value_order(ExactValue const &v) {
 	}
 	}
 }
 }
 
 
-void match_exact_values(ExactValue *x, ExactValue *y) {
+gb_internal void match_exact_values(ExactValue *x, ExactValue *y) {
 	if (exact_value_order(*y) < exact_value_order(*x)) {
 	if (exact_value_order(*y) < exact_value_order(*x)) {
 		match_exact_values(y, x);
 		match_exact_values(y, x);
 		return;
 		return;
@@ -687,7 +677,7 @@ void match_exact_values(ExactValue *x, ExactValue *y) {
 }
 }
 
 
 // TODO(bill): Allow for pointer arithmetic? Or are pointer slices good enough?
 // TODO(bill): Allow for pointer arithmetic? Or are pointer slices good enough?
-ExactValue exact_binary_operator_value(TokenKind op, ExactValue x, ExactValue y) {
+gb_internal ExactValue exact_binary_operator_value(TokenKind op, ExactValue x, ExactValue y) {
 	match_exact_values(&x, &y);
 	match_exact_values(&x, &y);
 
 
 	switch (x.kind) {
 	switch (x.kind) {
@@ -846,32 +836,32 @@ error:; // NOTE(bill): MSVC accepts this??? apparently you cannot declare variab
 	return empty_exact_value;
 	return empty_exact_value;
 }
 }
 
 
-gb_inline ExactValue exact_value_add(ExactValue const &x, ExactValue const &y) {
+gb_internal gb_inline ExactValue exact_value_add(ExactValue const &x, ExactValue const &y) {
 	return exact_binary_operator_value(Token_Add, x, y);
 	return exact_binary_operator_value(Token_Add, x, y);
 }
 }
-gb_inline ExactValue exact_value_sub(ExactValue const &x, ExactValue const &y) {
+gb_internal gb_inline ExactValue exact_value_sub(ExactValue const &x, ExactValue const &y) {
 	return exact_binary_operator_value(Token_Sub, x, y);
 	return exact_binary_operator_value(Token_Sub, x, y);
 }
 }
-gb_inline ExactValue exact_value_mul(ExactValue const &x, ExactValue const &y) {
+gb_internal gb_inline ExactValue exact_value_mul(ExactValue const &x, ExactValue const &y) {
 	return exact_binary_operator_value(Token_Mul, x, y);
 	return exact_binary_operator_value(Token_Mul, x, y);
 }
 }
-gb_inline ExactValue exact_value_quo(ExactValue const &x, ExactValue const &y) {
+gb_internal gb_inline ExactValue exact_value_quo(ExactValue const &x, ExactValue const &y) {
 	return exact_binary_operator_value(Token_Quo, x, y);
 	return exact_binary_operator_value(Token_Quo, x, y);
 }
 }
-gb_inline ExactValue exact_value_shift(TokenKind op, ExactValue const &x, ExactValue const &y) {
+gb_internal gb_inline ExactValue exact_value_shift(TokenKind op, ExactValue const &x, ExactValue const &y) {
 	return exact_binary_operator_value(op, x, y);
 	return exact_binary_operator_value(op, x, y);
 }
 }
 
 
-gb_inline ExactValue exact_value_increment_one(ExactValue const &x) {
+gb_internal gb_inline ExactValue exact_value_increment_one(ExactValue const &x) {
 	return exact_binary_operator_value(Token_Add, x, exact_value_i64(1));
 	return exact_binary_operator_value(Token_Add, x, exact_value_i64(1));
 }
 }
 
 
 
 
-i32 cmp_f64(f64 a, f64 b) {
+gb_internal gb_inline i32 cmp_f64(f64 a, f64 b) {
 	return (a > b) - (a < b);
 	return (a > b) - (a < b);
 }
 }
 
 
-bool compare_exact_values(TokenKind op, ExactValue x, ExactValue y) {
+gb_internal bool compare_exact_values(TokenKind op, ExactValue x, ExactValue y) {
 	match_exact_values(&x, &y);
 	match_exact_values(&x, &y);
 
 
 	switch (x.kind) {
 	switch (x.kind) {
@@ -969,12 +959,12 @@ bool compare_exact_values(TokenKind op, ExactValue x, ExactValue y) {
 	return false;
 	return false;
 }
 }
 
 
-Entity *strip_entity_wrapping(Ast *expr);
-Entity *strip_entity_wrapping(Entity *e);
+gb_internal Entity *strip_entity_wrapping(Ast *expr);
+gb_internal Entity *strip_entity_wrapping(Entity *e);
 
 
-gbString write_expr_to_string(gbString str, Ast *node, bool shorthand);
+gb_internal gbString write_expr_to_string(gbString str, Ast *node, bool shorthand);
 
 
-gbString write_exact_value_to_string(gbString str, ExactValue const &v, isize string_limit=36) {
+gb_internal gbString write_exact_value_to_string(gbString str, ExactValue const &v, isize string_limit=36) {
 	switch (v.kind) {
 	switch (v.kind) {
 	case ExactValue_Invalid:
 	case ExactValue_Invalid:
 		return str;
 		return str;
@@ -1017,6 +1007,6 @@ gbString write_exact_value_to_string(gbString str, ExactValue const &v, isize st
 	return str;
 	return str;
 };
 };
 
 
-gbString exact_value_to_string(ExactValue const &v, isize string_limit=36) {
+gb_internal gbString exact_value_to_string(ExactValue const &v, isize string_limit=36) {
 	return write_exact_value_to_string(gb_string_make(heap_allocator(), ""), v, string_limit);
 	return write_exact_value_to_string(gb_string_make(heap_allocator(), ""), v, string_limit);
 }
 }

+ 77 - 77
src/llvm_abi.cpp

@@ -18,21 +18,21 @@ struct lbArgType {
 };
 };
 
 
 
 
-i64 lb_sizeof(LLVMTypeRef type);
-i64 lb_alignof(LLVMTypeRef type);
+gb_internal i64 lb_sizeof(LLVMTypeRef type);
+gb_internal i64 lb_alignof(LLVMTypeRef type);
 
 
-lbArgType lb_arg_type_direct(LLVMTypeRef type, LLVMTypeRef cast_type, LLVMTypeRef pad_type, LLVMAttributeRef attr) {
+gb_internal lbArgType lb_arg_type_direct(LLVMTypeRef type, LLVMTypeRef cast_type, LLVMTypeRef pad_type, LLVMAttributeRef attr) {
 	return lbArgType{lbArg_Direct, type, cast_type, pad_type, attr, nullptr, 0, false};
 	return lbArgType{lbArg_Direct, type, cast_type, pad_type, attr, nullptr, 0, false};
 }
 }
-lbArgType lb_arg_type_direct(LLVMTypeRef type) {
+gb_internal lbArgType lb_arg_type_direct(LLVMTypeRef type) {
 	return lb_arg_type_direct(type, nullptr, nullptr, nullptr);
 	return lb_arg_type_direct(type, nullptr, nullptr, nullptr);
 }
 }
 
 
-lbArgType lb_arg_type_indirect(LLVMTypeRef type, LLVMAttributeRef attr) {
+gb_internal lbArgType lb_arg_type_indirect(LLVMTypeRef type, LLVMAttributeRef attr) {
 	return lbArgType{lbArg_Indirect, type, nullptr, nullptr, attr, nullptr, 0, false};
 	return lbArgType{lbArg_Indirect, type, nullptr, nullptr, attr, nullptr, 0, false};
 }
 }
 
 
-lbArgType lb_arg_type_indirect_byval(LLVMContextRef c, LLVMTypeRef type) {
+gb_internal lbArgType lb_arg_type_indirect_byval(LLVMContextRef c, LLVMTypeRef type) {
 	i64 alignment = lb_alignof(type);
 	i64 alignment = lb_alignof(type);
 	alignment = gb_max(alignment, 8);
 	alignment = gb_max(alignment, 8);
 
 
@@ -41,7 +41,7 @@ lbArgType lb_arg_type_indirect_byval(LLVMContextRef c, LLVMTypeRef type) {
 	return lbArgType{lbArg_Indirect, type, nullptr, nullptr, byval_attr, align_attr, alignment, true};
 	return lbArgType{lbArg_Indirect, type, nullptr, nullptr, byval_attr, align_attr, alignment, true};
 }
 }
 
 
-lbArgType lb_arg_type_ignore(LLVMTypeRef type) {
+gb_internal lbArgType lb_arg_type_ignore(LLVMTypeRef type) {
 	return lbArgType{lbArg_Ignore, type, nullptr, nullptr, nullptr, nullptr, 0, false};
 	return lbArgType{lbArg_Ignore, type, nullptr, nullptr, nullptr, nullptr, 0, false};
 }
 }
 
 
@@ -55,24 +55,24 @@ struct lbFunctionType {
 	isize            original_arg_count;
 	isize            original_arg_count;
 };
 };
 
 
-gbAllocator lb_function_type_args_allocator(void) {
+gb_internal gbAllocator lb_function_type_args_allocator(void) {
 	return heap_allocator();
 	return heap_allocator();
 }
 }
 
 
 
 
-i64 llvm_align_formula(i64 off, i64 a) {
+gb_internal gb_inline i64 llvm_align_formula(i64 off, i64 a) {
 	return (off + a - 1) / a * a;
 	return (off + a - 1) / a * a;
 }
 }
 
 
 
 
-bool lb_is_type_kind(LLVMTypeRef type, LLVMTypeKind kind) {
+gb_internal bool lb_is_type_kind(LLVMTypeRef type, LLVMTypeKind kind) {
 	if (type == nullptr) {
 	if (type == nullptr) {
 		return false;
 		return false;
 	}
 	}
 	return LLVMGetTypeKind(type) == kind;
 	return LLVMGetTypeKind(type) == kind;
 }
 }
 
 
-LLVMTypeRef lb_function_type_to_llvm_raw(lbFunctionType *ft, bool is_var_arg) {
+gb_internal LLVMTypeRef lb_function_type_to_llvm_raw(lbFunctionType *ft, bool is_var_arg) {
 	unsigned arg_count = cast(unsigned)ft->args.count;
 	unsigned arg_count = cast(unsigned)ft->args.count;
 	unsigned offset = 0;
 	unsigned offset = 0;
 
 
@@ -130,7 +130,7 @@ LLVMTypeRef lb_function_type_to_llvm_raw(lbFunctionType *ft, bool is_var_arg) {
 // }
 // }
 
 
 
 
-void lb_add_function_type_attributes(LLVMValueRef fn, lbFunctionType *ft, ProcCallingConvention calling_convention) {
+gb_internal void lb_add_function_type_attributes(LLVMValueRef fn, lbFunctionType *ft, ProcCallingConvention calling_convention) {
 	if (ft == nullptr) {
 	if (ft == nullptr) {
 		return;
 		return;
 	}
 	}
@@ -201,7 +201,7 @@ void lb_add_function_type_attributes(LLVMValueRef fn, lbFunctionType *ft, ProcCa
 }
 }
 
 
 
 
-i64 lb_sizeof(LLVMTypeRef type) {
+gb_internal i64 lb_sizeof(LLVMTypeRef type) {
 	LLVMTypeKind kind = LLVMGetTypeKind(type);
 	LLVMTypeKind kind = LLVMGetTypeKind(type);
 	switch (kind) {
 	switch (kind) {
 	case LLVMVoidTypeKind:
 	case LLVMVoidTypeKind:
@@ -267,7 +267,7 @@ i64 lb_sizeof(LLVMTypeRef type) {
 	return 0;
 	return 0;
 }
 }
 
 
-i64 lb_alignof(LLVMTypeRef type) {
+gb_internal i64 lb_alignof(LLVMTypeRef type) {
 	LLVMTypeKind kind = LLVMGetTypeKind(type);
 	LLVMTypeKind kind = LLVMGetTypeKind(type);
 	switch (kind) {
 	switch (kind) {
 	case LLVMVoidTypeKind:
 	case LLVMVoidTypeKind:
@@ -333,7 +333,7 @@ typedef LB_ABI_INFO(lbAbiInfoType);
 typedef LB_ABI_COMPUTE_RETURN_TYPE(lbAbiComputeReturnType);
 typedef LB_ABI_COMPUTE_RETURN_TYPE(lbAbiComputeReturnType);
 
 
 
 
-lbArgType lb_abi_modify_return_is_tuple(lbFunctionType *ft, LLVMContextRef c, LLVMTypeRef return_type, lbAbiComputeReturnType *compute_return_type) {
+gb_internal lbArgType lb_abi_modify_return_is_tuple(lbFunctionType *ft, LLVMContextRef c, LLVMTypeRef return_type, lbAbiComputeReturnType *compute_return_type) {
 	GB_ASSERT(return_type != nullptr);
 	GB_ASSERT(return_type != nullptr);
 	GB_ASSERT(compute_return_type != nullptr);
 	GB_ASSERT(compute_return_type != nullptr);
 
 
@@ -370,10 +370,10 @@ lbArgType lb_abi_modify_return_is_tuple(lbFunctionType *ft, LLVMContextRef c, LL
 
 
 // NOTE(bill): I hate `namespace` in C++ but this is just because I don't want to prefix everything
 // NOTE(bill): I hate `namespace` in C++ but this is just because I don't want to prefix everything
 namespace lbAbi386 {
 namespace lbAbi386 {
-	Array<lbArgType> compute_arg_types(LLVMContextRef c, LLVMTypeRef *arg_types, unsigned arg_count);
-	LB_ABI_COMPUTE_RETURN_TYPE(compute_return_type);
+	gb_internal Array<lbArgType> compute_arg_types(LLVMContextRef c, LLVMTypeRef *arg_types, unsigned arg_count);
+	gb_internal LB_ABI_COMPUTE_RETURN_TYPE(compute_return_type);
 
 
-	LB_ABI_INFO(abi_info) {
+	gb_internal LB_ABI_INFO(abi_info) {
 		lbFunctionType *ft = gb_alloc_item(permanent_allocator(), lbFunctionType);
 		lbFunctionType *ft = gb_alloc_item(permanent_allocator(), lbFunctionType);
 		ft->ctx = c;
 		ft->ctx = c;
 		ft->args = compute_arg_types(c, arg_types, arg_count);
 		ft->args = compute_arg_types(c, arg_types, arg_count);
@@ -382,7 +382,7 @@ namespace lbAbi386 {
 		return ft;
 		return ft;
 	}
 	}
 
 
-	lbArgType non_struct(LLVMContextRef c, LLVMTypeRef type, bool is_return) {
+	gb_internal lbArgType non_struct(LLVMContextRef c, LLVMTypeRef type, bool is_return) {
 		if (!is_return && lb_sizeof(type) > 8) {
 		if (!is_return && lb_sizeof(type) > 8) {
 			return lb_arg_type_indirect(type, nullptr);
 			return lb_arg_type_indirect(type, nullptr);
 		}
 		}
@@ -409,7 +409,7 @@ namespace lbAbi386 {
 		return lb_arg_type_direct(type, nullptr, nullptr, attr);
 		return lb_arg_type_direct(type, nullptr, nullptr, attr);
 	}
 	}
 
 
-	Array<lbArgType> compute_arg_types(LLVMContextRef c, LLVMTypeRef *arg_types, unsigned arg_count) {
+	gb_internal Array<lbArgType> compute_arg_types(LLVMContextRef c, LLVMTypeRef *arg_types, unsigned arg_count) {
 		auto args = array_make<lbArgType>(lb_function_type_args_allocator(), arg_count);
 		auto args = array_make<lbArgType>(lb_function_type_args_allocator(), arg_count);
 
 
 		for (unsigned i = 0; i < arg_count; i++) {
 		for (unsigned i = 0; i < arg_count; i++) {
@@ -429,7 +429,7 @@ namespace lbAbi386 {
 		return args;
 		return args;
 	}
 	}
 
 
-	LB_ABI_COMPUTE_RETURN_TYPE(compute_return_type) {
+	gb_internal LB_ABI_COMPUTE_RETURN_TYPE(compute_return_type) {
 		if (!return_is_defined) {
 		if (!return_is_defined) {
 			return lb_arg_type_direct(LLVMVoidTypeInContext(c));
 			return lb_arg_type_direct(LLVMVoidTypeInContext(c));
 		} else if (lb_is_type_kind(return_type, LLVMStructTypeKind) || lb_is_type_kind(return_type, LLVMArrayTypeKind)) {
 		} else if (lb_is_type_kind(return_type, LLVMStructTypeKind) || lb_is_type_kind(return_type, LLVMArrayTypeKind)) {
@@ -451,10 +451,10 @@ namespace lbAbi386 {
 };
 };
 
 
 namespace lbAbiAmd64Win64 {
 namespace lbAbiAmd64Win64 {
-	Array<lbArgType> compute_arg_types(LLVMContextRef c, LLVMTypeRef *arg_types, unsigned arg_count);
-	LB_ABI_COMPUTE_RETURN_TYPE(compute_return_type);
+	gb_internal Array<lbArgType> compute_arg_types(LLVMContextRef c, LLVMTypeRef *arg_types, unsigned arg_count);
+	gb_internal LB_ABI_COMPUTE_RETURN_TYPE(compute_return_type);
 
 
-	LB_ABI_INFO(abi_info) {
+	gb_internal LB_ABI_INFO(abi_info) {
 		lbFunctionType *ft = gb_alloc_item(permanent_allocator(), lbFunctionType);
 		lbFunctionType *ft = gb_alloc_item(permanent_allocator(), lbFunctionType);
 		ft->ctx = c;
 		ft->ctx = c;
 		ft->args = compute_arg_types(c, arg_types, arg_count);
 		ft->args = compute_arg_types(c, arg_types, arg_count);
@@ -463,7 +463,7 @@ namespace lbAbiAmd64Win64 {
 		return ft;
 		return ft;
 	}
 	}
 
 
-	Array<lbArgType> compute_arg_types(LLVMContextRef c, LLVMTypeRef *arg_types, unsigned arg_count) {
+	gb_internal Array<lbArgType> compute_arg_types(LLVMContextRef c, LLVMTypeRef *arg_types, unsigned arg_count) {
 		auto args = array_make<lbArgType>(lb_function_type_args_allocator(), arg_count);
 		auto args = array_make<lbArgType>(lb_function_type_args_allocator(), arg_count);
 
 
 		for (unsigned i = 0; i < arg_count; i++) {
 		for (unsigned i = 0; i < arg_count; i++) {
@@ -489,7 +489,7 @@ namespace lbAbiAmd64Win64 {
 		return args;
 		return args;
 	}
 	}
 
 
-	LB_ABI_COMPUTE_RETURN_TYPE(compute_return_type) {
+	gb_internal LB_ABI_COMPUTE_RETURN_TYPE(compute_return_type) {
 		if (!return_is_defined) {
 		if (!return_is_defined) {
 			return lb_arg_type_direct(LLVMVoidTypeInContext(c));
 			return lb_arg_type_direct(LLVMVoidTypeInContext(c));
 		} else if (lb_is_type_kind(return_type, LLVMStructTypeKind) || lb_is_type_kind(return_type, LLVMArrayTypeKind)) {
 		} else if (lb_is_type_kind(return_type, LLVMStructTypeKind) || lb_is_type_kind(return_type, LLVMArrayTypeKind)) {
@@ -530,7 +530,7 @@ namespace lbAbiAmd64SysV {
 		RegClass_Memory,
 		RegClass_Memory,
 	};
 	};
 
 
-	bool is_sse(RegClass reg_class) {
+	gb_internal bool is_sse(RegClass reg_class) {
 		switch (reg_class) {
 		switch (reg_class) {
 		case RegClass_SSEFs:
 		case RegClass_SSEFs:
 		case RegClass_SSEFv:
 		case RegClass_SSEFv:
@@ -546,7 +546,7 @@ namespace lbAbiAmd64SysV {
 		return false;
 		return false;
 	}
 	}
 
 
-	void all_mem(Array<RegClass> *cs) {
+	gb_internal void all_mem(Array<RegClass> *cs) {
 		for_array(i, *cs) {
 		for_array(i, *cs) {
 			(*cs)[i] = RegClass_Memory;
 			(*cs)[i] = RegClass_Memory;
 		}
 		}
@@ -558,14 +558,14 @@ namespace lbAbiAmd64SysV {
 		Amd64TypeAttribute_StructRect,
 		Amd64TypeAttribute_StructRect,
 	};
 	};
 
 
-	LB_ABI_COMPUTE_RETURN_TYPE(compute_return_type);
-	void classify_with(LLVMTypeRef t, Array<RegClass> *cls, i64 ix, i64 off);
-	void fixup(LLVMTypeRef t, Array<RegClass> *cls);
-	lbArgType amd64_type(LLVMContextRef c, LLVMTypeRef type, Amd64TypeAttributeKind attribute_kind, ProcCallingConvention calling_convention);
-	Array<RegClass> classify(LLVMTypeRef t);
-	LLVMTypeRef llreg(LLVMContextRef c, Array<RegClass> const &reg_classes);
+	gb_internal LB_ABI_COMPUTE_RETURN_TYPE(compute_return_type);
+	gb_internal void classify_with(LLVMTypeRef t, Array<RegClass> *cls, i64 ix, i64 off);
+	gb_internal void fixup(LLVMTypeRef t, Array<RegClass> *cls);
+	gb_internal lbArgType amd64_type(LLVMContextRef c, LLVMTypeRef type, Amd64TypeAttributeKind attribute_kind, ProcCallingConvention calling_convention);
+	gb_internal Array<RegClass> classify(LLVMTypeRef t);
+	gb_internal LLVMTypeRef llreg(LLVMContextRef c, Array<RegClass> const &reg_classes);
 
 
-	LB_ABI_INFO(abi_info) {
+	gb_internal LB_ABI_INFO(abi_info) {
 		lbFunctionType *ft = gb_alloc_item(permanent_allocator(), lbFunctionType);
 		lbFunctionType *ft = gb_alloc_item(permanent_allocator(), lbFunctionType);
 		ft->ctx = c;
 		ft->ctx = c;
 		ft->calling_convention = calling_convention;
 		ft->calling_convention = calling_convention;
@@ -584,7 +584,7 @@ namespace lbAbiAmd64SysV {
 		return ft;
 		return ft;
 	}
 	}
 
 
-	bool is_mem_cls(Array<RegClass> const &cls, Amd64TypeAttributeKind attribute_kind) {
+	gb_internal bool is_mem_cls(Array<RegClass> const &cls, Amd64TypeAttributeKind attribute_kind) {
 		if (attribute_kind == Amd64TypeAttribute_ByVal) {
 		if (attribute_kind == Amd64TypeAttribute_ByVal) {
 			if (cls.count == 0) {
 			if (cls.count == 0) {
 				return false;
 				return false;
@@ -600,7 +600,7 @@ namespace lbAbiAmd64SysV {
 		return false;
 		return false;
 	}
 	}
 
 
-	bool is_register(LLVMTypeRef type) {
+	gb_internal bool is_register(LLVMTypeRef type) {
 		LLVMTypeKind kind = LLVMGetTypeKind(type);
 		LLVMTypeKind kind = LLVMGetTypeKind(type);
 		i64 sz = lb_sizeof(type);
 		i64 sz = lb_sizeof(type);
 		if (sz == 0) {
 		if (sz == 0) {
@@ -617,7 +617,7 @@ namespace lbAbiAmd64SysV {
 		return false;
 		return false;
 	}
 	}
 
 
-	bool is_llvm_type_slice_like(LLVMTypeRef type) {
+	gb_internal bool is_llvm_type_slice_like(LLVMTypeRef type) {
 		if (!lb_is_type_kind(type, LLVMStructTypeKind)) {
 		if (!lb_is_type_kind(type, LLVMStructTypeKind)) {
 			return false;
 			return false;
 		}
 		}
@@ -633,7 +633,7 @@ namespace lbAbiAmd64SysV {
 
 
 	}
 	}
 
 
-	lbArgType amd64_type(LLVMContextRef c, LLVMTypeRef type, Amd64TypeAttributeKind attribute_kind, ProcCallingConvention calling_convention) {
+	gb_internal lbArgType amd64_type(LLVMContextRef c, LLVMTypeRef type, Amd64TypeAttributeKind attribute_kind, ProcCallingConvention calling_convention) {
 		if (is_register(type)) {
 		if (is_register(type)) {
 			LLVMAttributeRef attribute = nullptr;
 			LLVMAttributeRef attribute = nullptr;
 			if (type == LLVMInt1TypeInContext(c)) {
 			if (type == LLVMInt1TypeInContext(c)) {
@@ -668,7 +668,7 @@ namespace lbAbiAmd64SysV {
 		}
 		}
 	}
 	}
 
 
-	lbArgType non_struct(LLVMContextRef c, LLVMTypeRef type) {
+	gb_internal lbArgType non_struct(LLVMContextRef c, LLVMTypeRef type) {
 		LLVMAttributeRef attr = nullptr;
 		LLVMAttributeRef attr = nullptr;
 		LLVMTypeRef i1 = LLVMInt1TypeInContext(c);
 		LLVMTypeRef i1 = LLVMInt1TypeInContext(c);
 		if (type == i1) {
 		if (type == i1) {
@@ -677,7 +677,7 @@ namespace lbAbiAmd64SysV {
 		return lb_arg_type_direct(type, nullptr, nullptr, attr);
 		return lb_arg_type_direct(type, nullptr, nullptr, attr);
 	}
 	}
 
 
-	Array<RegClass> classify(LLVMTypeRef t) {
+	gb_internal Array<RegClass> classify(LLVMTypeRef t) {
 		i64 sz = lb_sizeof(t);
 		i64 sz = lb_sizeof(t);
 		i64 words = (sz + 7)/8;
 		i64 words = (sz + 7)/8;
 		auto reg_classes = array_make<RegClass>(heap_allocator(), cast(isize)words);
 		auto reg_classes = array_make<RegClass>(heap_allocator(), cast(isize)words);
@@ -690,7 +690,7 @@ namespace lbAbiAmd64SysV {
 		return reg_classes;
 		return reg_classes;
 	}
 	}
 
 
-	void unify(Array<RegClass> *cls, i64 i, RegClass const newv) {
+	gb_internal void unify(Array<RegClass> *cls, i64 i, RegClass const newv) {
 		RegClass const oldv = (*cls)[cast(isize)i];
 		RegClass const oldv = (*cls)[cast(isize)i];
 		if (oldv == newv) {
 		if (oldv == newv) {
 			return;
 			return;
@@ -726,7 +726,7 @@ namespace lbAbiAmd64SysV {
 		(*cls)[cast(isize)i] = to_write;
 		(*cls)[cast(isize)i] = to_write;
 	}
 	}
 
 
-	void fixup(LLVMTypeRef t, Array<RegClass> *cls) {
+	gb_internal void fixup(LLVMTypeRef t, Array<RegClass> *cls) {
 		i64 i = 0;
 		i64 i = 0;
 		i64 e = cls->count;
 		i64 e = cls->count;
 		if (e > 2 && (lb_is_type_kind(t, LLVMStructTypeKind) ||
 		if (e > 2 && (lb_is_type_kind(t, LLVMStructTypeKind) ||
@@ -773,7 +773,7 @@ namespace lbAbiAmd64SysV {
 		}
 		}
 	}
 	}
 
 
-	unsigned llvec_len(Array<RegClass> const &reg_classes, isize offset) {
+	gb_internal unsigned llvec_len(Array<RegClass> const &reg_classes, isize offset) {
 		unsigned len = 1;
 		unsigned len = 1;
 		for (isize i = offset; i < reg_classes.count; i++) {
 		for (isize i = offset; i < reg_classes.count; i++) {
 			if (reg_classes[i] != RegClass_SSEUp) {
 			if (reg_classes[i] != RegClass_SSEUp) {
@@ -785,7 +785,7 @@ namespace lbAbiAmd64SysV {
 	}
 	}
 
 
 
 
-	LLVMTypeRef llreg(LLVMContextRef c, Array<RegClass> const &reg_classes) {
+	gb_internal LLVMTypeRef llreg(LLVMContextRef c, Array<RegClass> const &reg_classes) {
 		auto types = array_make<LLVMTypeRef>(heap_allocator(), 0, reg_classes.count);
 		auto types = array_make<LLVMTypeRef>(heap_allocator(), 0, reg_classes.count);
 		for (isize i = 0; i < reg_classes.count; /**/) {
 		for (isize i = 0; i < reg_classes.count; /**/) {
 			RegClass reg_class = reg_classes[i];
 			RegClass reg_class = reg_classes[i];
@@ -854,7 +854,7 @@ namespace lbAbiAmd64SysV {
 		return LLVMStructTypeInContext(c, types.data, cast(unsigned)types.count, false);
 		return LLVMStructTypeInContext(c, types.data, cast(unsigned)types.count, false);
 	}
 	}
 
 
-	void classify_with(LLVMTypeRef t, Array<RegClass> *cls, i64 ix, i64 off) {
+	gb_internal void classify_with(LLVMTypeRef t, Array<RegClass> *cls, i64 ix, i64 off) {
 		i64 t_align = lb_alignof(t);
 		i64 t_align = lb_alignof(t);
 		i64 t_size  = lb_sizeof(t);
 		i64 t_size  = lb_sizeof(t);
 
 
@@ -955,7 +955,7 @@ namespace lbAbiAmd64SysV {
 		}
 		}
 	}
 	}
 
 
-	LB_ABI_COMPUTE_RETURN_TYPE(compute_return_type) {
+	gb_internal LB_ABI_COMPUTE_RETURN_TYPE(compute_return_type) {
 		if (!return_is_defined) {
 		if (!return_is_defined) {
 			return lb_arg_type_direct(LLVMVoidTypeInContext(c));
 			return lb_arg_type_direct(LLVMVoidTypeInContext(c));
 		} else if (lb_is_type_kind(return_type, LLVMStructTypeKind)) {
 		} else if (lb_is_type_kind(return_type, LLVMStructTypeKind)) {
@@ -980,11 +980,11 @@ namespace lbAbiAmd64SysV {
 
 
 
 
 namespace lbAbiArm64 {
 namespace lbAbiArm64 {
-	Array<lbArgType> compute_arg_types(LLVMContextRef c, LLVMTypeRef *arg_types, unsigned arg_count);
-	LB_ABI_COMPUTE_RETURN_TYPE(compute_return_type);
-	bool is_homogenous_aggregate(LLVMContextRef c, LLVMTypeRef type, LLVMTypeRef *base_type_, unsigned *member_count_);
+	gb_internal Array<lbArgType> compute_arg_types(LLVMContextRef c, LLVMTypeRef *arg_types, unsigned arg_count);
+	gb_internal LB_ABI_COMPUTE_RETURN_TYPE(compute_return_type);
+	gb_internal bool is_homogenous_aggregate(LLVMContextRef c, LLVMTypeRef type, LLVMTypeRef *base_type_, unsigned *member_count_);
 
 
-	LB_ABI_INFO(abi_info) {
+	gb_internal LB_ABI_INFO(abi_info) {
 		lbFunctionType *ft = gb_alloc_item(permanent_allocator(), lbFunctionType);
 		lbFunctionType *ft = gb_alloc_item(permanent_allocator(), lbFunctionType);
 		ft->ctx = c;
 		ft->ctx = c;
 		ft->args = compute_arg_types(c, arg_types, arg_count);
 		ft->args = compute_arg_types(c, arg_types, arg_count);
@@ -993,7 +993,7 @@ namespace lbAbiArm64 {
 		return ft;
 		return ft;
 	}
 	}
 
 
-	bool is_register(LLVMTypeRef type) {
+	gb_internal bool is_register(LLVMTypeRef type) {
 		LLVMTypeKind kind = LLVMGetTypeKind(type);
 		LLVMTypeKind kind = LLVMGetTypeKind(type);
 		switch (kind) {
 		switch (kind) {
 		case LLVMIntegerTypeKind:
 		case LLVMIntegerTypeKind:
@@ -1006,7 +1006,7 @@ namespace lbAbiArm64 {
 		return false;
 		return false;
 	}
 	}
 
 
-	lbArgType non_struct(LLVMContextRef c, LLVMTypeRef type) {
+	gb_internal lbArgType non_struct(LLVMContextRef c, LLVMTypeRef type) {
 		LLVMAttributeRef attr = nullptr;
 		LLVMAttributeRef attr = nullptr;
 		LLVMTypeRef i1 = LLVMInt1TypeInContext(c);
 		LLVMTypeRef i1 = LLVMInt1TypeInContext(c);
 		if (type == i1) {
 		if (type == i1) {
@@ -1015,7 +1015,7 @@ namespace lbAbiArm64 {
 		return lb_arg_type_direct(type, nullptr, nullptr, attr);
 		return lb_arg_type_direct(type, nullptr, nullptr, attr);
 	}
 	}
 
 
-	bool is_homogenous_array(LLVMContextRef c, LLVMTypeRef type, LLVMTypeRef *base_type_, unsigned *member_count_) {
+	gb_internal bool is_homogenous_array(LLVMContextRef c, LLVMTypeRef type, LLVMTypeRef *base_type_, unsigned *member_count_) {
 		GB_ASSERT(lb_is_type_kind(type, LLVMArrayTypeKind));
 		GB_ASSERT(lb_is_type_kind(type, LLVMArrayTypeKind));
 		unsigned len = LLVMGetArrayLength(type);
 		unsigned len = LLVMGetArrayLength(type);
 		if (len == 0) {
 		if (len == 0) {
@@ -1032,7 +1032,7 @@ namespace lbAbiArm64 {
 		}
 		}
 		return false;
 		return false;
 	}
 	}
-	bool is_homogenous_struct(LLVMContextRef c, LLVMTypeRef type, LLVMTypeRef *base_type_, unsigned *member_count_) {
+	gb_internal bool is_homogenous_struct(LLVMContextRef c, LLVMTypeRef type, LLVMTypeRef *base_type_, unsigned *member_count_) {
 		GB_ASSERT(lb_is_type_kind(type, LLVMStructTypeKind));
 		GB_ASSERT(lb_is_type_kind(type, LLVMStructTypeKind));
 		unsigned elem_count = LLVMCountStructElementTypes(type);
 		unsigned elem_count = LLVMCountStructElementTypes(type);
 		if (elem_count == 0) {
 		if (elem_count == 0) {
@@ -1075,7 +1075,7 @@ namespace lbAbiArm64 {
 	}
 	}
 
 
 
 
-	bool is_homogenous_aggregate(LLVMContextRef c, LLVMTypeRef type, LLVMTypeRef *base_type_, unsigned *member_count_) {
+	gb_internal bool is_homogenous_aggregate(LLVMContextRef c, LLVMTypeRef type, LLVMTypeRef *base_type_, unsigned *member_count_) {
 		LLVMTypeKind kind = LLVMGetTypeKind(type);
 		LLVMTypeKind kind = LLVMGetTypeKind(type);
 		switch (kind) {
 		switch (kind) {
 		case LLVMFloatTypeKind:
 		case LLVMFloatTypeKind:
@@ -1091,11 +1091,11 @@ namespace lbAbiArm64 {
 		return false;
 		return false;
 	}
 	}
 
 
-	unsigned is_homogenous_aggregate_small_enough(LLVMTypeRef base_type, unsigned member_count) {
+	gb_internal unsigned is_homogenous_aggregate_small_enough(LLVMTypeRef base_type, unsigned member_count) {
 		return (member_count <= 4);
 		return (member_count <= 4);
 	}
 	}
 
 
-	LB_ABI_COMPUTE_RETURN_TYPE(compute_return_type) {
+	gb_internal LB_ABI_COMPUTE_RETURN_TYPE(compute_return_type) {
 		LLVMTypeRef homo_base_type = nullptr;
 		LLVMTypeRef homo_base_type = nullptr;
 		unsigned homo_member_count = 0;
 		unsigned homo_member_count = 0;
 
 
@@ -1142,7 +1142,7 @@ namespace lbAbiArm64 {
 		}
 		}
 	}
 	}
     
     
-	Array<lbArgType> compute_arg_types(LLVMContextRef c, LLVMTypeRef *arg_types, unsigned arg_count) {
+	gb_internal Array<lbArgType> compute_arg_types(LLVMContextRef c, LLVMTypeRef *arg_types, unsigned arg_count) {
 		auto args = array_make<lbArgType>(lb_function_type_args_allocator(), arg_count);
 		auto args = array_make<lbArgType>(lb_function_type_args_allocator(), arg_count);
 
 
 		for (unsigned i = 0; i < arg_count; i++) {
 		for (unsigned i = 0; i < arg_count; i++) {
@@ -1188,12 +1188,12 @@ namespace lbAbiWasm {
 		            The approach taken optimizes for passing things in multiple
 		            The approach taken optimizes for passing things in multiple
 		            registers/arguments if possible rather than by pointer.
 		            registers/arguments if possible rather than by pointer.
 	*/
 	*/
-	Array<lbArgType> compute_arg_types(LLVMContextRef c, LLVMTypeRef *arg_types, unsigned arg_count);
-	LB_ABI_COMPUTE_RETURN_TYPE(compute_return_type);
+	gb_internal Array<lbArgType> compute_arg_types(LLVMContextRef c, LLVMTypeRef *arg_types, unsigned arg_count);
+	gb_internal LB_ABI_COMPUTE_RETURN_TYPE(compute_return_type);
 
 
 	enum {MAX_DIRECT_STRUCT_SIZE = 32};
 	enum {MAX_DIRECT_STRUCT_SIZE = 32};
 
 
-	LB_ABI_INFO(abi_info) {
+	gb_internal LB_ABI_INFO(abi_info) {
 		lbFunctionType *ft = gb_alloc_item(permanent_allocator(), lbFunctionType);
 		lbFunctionType *ft = gb_alloc_item(permanent_allocator(), lbFunctionType);
 		ft->ctx = c;
 		ft->ctx = c;
 		ft->args = compute_arg_types(c, arg_types, arg_count);
 		ft->args = compute_arg_types(c, arg_types, arg_count);
@@ -1202,7 +1202,7 @@ namespace lbAbiWasm {
 		return ft;
 		return ft;
 	}
 	}
 
 
-	lbArgType non_struct(LLVMContextRef c, LLVMTypeRef type, bool is_return) {
+	gb_internal lbArgType non_struct(LLVMContextRef c, LLVMTypeRef type, bool is_return) {
 		if (!is_return && type == LLVMIntTypeInContext(c, 128)) {
 		if (!is_return && type == LLVMIntTypeInContext(c, 128)) {
 			LLVMTypeRef cast_type = LLVMVectorType(LLVMInt64TypeInContext(c), 2);
 			LLVMTypeRef cast_type = LLVMVectorType(LLVMInt64TypeInContext(c), 2);
 			return lb_arg_type_direct(type, cast_type, nullptr, nullptr);
 			return lb_arg_type_direct(type, cast_type, nullptr, nullptr);
@@ -1220,7 +1220,7 @@ namespace lbAbiWasm {
 		return lb_arg_type_direct(type, nullptr, nullptr, attr);
 		return lb_arg_type_direct(type, nullptr, nullptr, attr);
 	}
 	}
 	
 	
-	bool is_basic_register_type(LLVMTypeRef type) {
+	gb_internal bool is_basic_register_type(LLVMTypeRef type) {
 		switch (LLVMGetTypeKind(type)) {
 		switch (LLVMGetTypeKind(type)) {
 		case LLVMHalfTypeKind:
 		case LLVMHalfTypeKind:
 		case LLVMFloatTypeKind:
 		case LLVMFloatTypeKind:
@@ -1233,7 +1233,7 @@ namespace lbAbiWasm {
 		return false;
 		return false;
 	}
 	}
 
 
-	bool type_can_be_direct(LLVMTypeRef type) {
+	gb_internal bool type_can_be_direct(LLVMTypeRef type) {
 		LLVMTypeKind kind = LLVMGetTypeKind(type);
 		LLVMTypeKind kind = LLVMGetTypeKind(type);
 		i64 sz = lb_sizeof(type);
 		i64 sz = lb_sizeof(type);
 		if (sz == 0) {
 		if (sz == 0) {
@@ -1259,7 +1259,7 @@ namespace lbAbiWasm {
 		return false;
 		return false;
 	}
 	}
 
 
-	lbArgType is_struct(LLVMContextRef c, LLVMTypeRef type) {
+	gb_internal lbArgType is_struct(LLVMContextRef c, LLVMTypeRef type) {
 		LLVMTypeKind kind = LLVMGetTypeKind(type);
 		LLVMTypeKind kind = LLVMGetTypeKind(type);
 		GB_ASSERT(kind == LLVMArrayTypeKind || kind == LLVMStructTypeKind);
 		GB_ASSERT(kind == LLVMArrayTypeKind || kind == LLVMStructTypeKind);
 		
 		
@@ -1274,7 +1274,7 @@ namespace lbAbiWasm {
 	}
 	}
 	
 	
 
 
-	Array<lbArgType> compute_arg_types(LLVMContextRef c, LLVMTypeRef *arg_types, unsigned arg_count) {
+	gb_internal Array<lbArgType> compute_arg_types(LLVMContextRef c, LLVMTypeRef *arg_types, unsigned arg_count) {
 		auto args = array_make<lbArgType>(lb_function_type_args_allocator(), arg_count);
 		auto args = array_make<lbArgType>(lb_function_type_args_allocator(), arg_count);
 
 
 		for (unsigned i = 0; i < arg_count; i++) {
 		for (unsigned i = 0; i < arg_count; i++) {
@@ -1289,7 +1289,7 @@ namespace lbAbiWasm {
 		return args;
 		return args;
 	}
 	}
 
 
-	LB_ABI_COMPUTE_RETURN_TYPE(compute_return_type) {
+	gb_internal LB_ABI_COMPUTE_RETURN_TYPE(compute_return_type) {
 		if (!return_is_defined) {
 		if (!return_is_defined) {
 			return lb_arg_type_direct(LLVMVoidTypeInContext(c));
 			return lb_arg_type_direct(LLVMVoidTypeInContext(c));
 		} else if (lb_is_type_kind(return_type, LLVMStructTypeKind) || lb_is_type_kind(return_type, LLVMArrayTypeKind)) {
 		} else if (lb_is_type_kind(return_type, LLVMStructTypeKind) || lb_is_type_kind(return_type, LLVMArrayTypeKind)) {
@@ -1315,10 +1315,10 @@ namespace lbAbiWasm {
 }
 }
 
 
 namespace lbAbiArm32 {
 namespace lbAbiArm32 {
-	Array<lbArgType> compute_arg_types(LLVMContextRef c, LLVMTypeRef *arg_types, unsigned arg_count, ProcCallingConvention calling_convention);
-	lbArgType compute_return_type(LLVMContextRef c, LLVMTypeRef return_type, bool return_is_defined);
+	gb_internal Array<lbArgType> compute_arg_types(LLVMContextRef c, LLVMTypeRef *arg_types, unsigned arg_count, ProcCallingConvention calling_convention);
+	gb_internal lbArgType compute_return_type(LLVMContextRef c, LLVMTypeRef return_type, bool return_is_defined);
 
 
-	LB_ABI_INFO(abi_info) {
+	gb_internal LB_ABI_INFO(abi_info) {
 		lbFunctionType *ft = gb_alloc_item(permanent_allocator(), lbFunctionType);
 		lbFunctionType *ft = gb_alloc_item(permanent_allocator(), lbFunctionType);
 		ft->ctx = c;
 		ft->ctx = c;
 		ft->args = compute_arg_types(c, arg_types, arg_count, calling_convention);
 		ft->args = compute_arg_types(c, arg_types, arg_count, calling_convention);
@@ -1327,7 +1327,7 @@ namespace lbAbiArm32 {
 		return ft;
 		return ft;
 	}
 	}
 
 
-	bool is_register(LLVMTypeRef type, bool is_return) {
+	gb_internal bool is_register(LLVMTypeRef type, bool is_return) {
 		LLVMTypeKind kind = LLVMGetTypeKind(type);
 		LLVMTypeKind kind = LLVMGetTypeKind(type);
 		switch (kind) {
 		switch (kind) {
 		case LLVMHalfTypeKind:
 		case LLVMHalfTypeKind:
@@ -1346,7 +1346,7 @@ namespace lbAbiArm32 {
 		return false;
 		return false;
 	}
 	}
 
 
-	lbArgType non_struct(LLVMContextRef c, LLVMTypeRef type, bool is_return) {
+	gb_internal lbArgType non_struct(LLVMContextRef c, LLVMTypeRef type, bool is_return) {
 		LLVMAttributeRef attr = nullptr;
 		LLVMAttributeRef attr = nullptr;
 		LLVMTypeRef i1 = LLVMInt1TypeInContext(c);
 		LLVMTypeRef i1 = LLVMInt1TypeInContext(c);
 		if (type == i1) {
 		if (type == i1) {
@@ -1355,7 +1355,7 @@ namespace lbAbiArm32 {
 		return lb_arg_type_direct(type, nullptr, nullptr, attr);
 		return lb_arg_type_direct(type, nullptr, nullptr, attr);
 	}
 	}
 
 
-	Array<lbArgType> compute_arg_types(LLVMContextRef c, LLVMTypeRef *arg_types, unsigned arg_count, ProcCallingConvention calling_convention) {
+	gb_internal Array<lbArgType> compute_arg_types(LLVMContextRef c, LLVMTypeRef *arg_types, unsigned arg_count, ProcCallingConvention calling_convention) {
 		auto args = array_make<lbArgType>(lb_function_type_args_allocator(), arg_count);
 		auto args = array_make<lbArgType>(lb_function_type_args_allocator(), arg_count);
 
 
 		for (unsigned i = 0; i < arg_count; i++) {
 		for (unsigned i = 0; i < arg_count; i++) {
@@ -1380,7 +1380,7 @@ namespace lbAbiArm32 {
 		return args;
 		return args;
 	}
 	}
 
 
-	lbArgType compute_return_type(LLVMContextRef c, LLVMTypeRef return_type, bool return_is_defined) {
+	gb_internal lbArgType compute_return_type(LLVMContextRef c, LLVMTypeRef return_type, bool return_is_defined) {
 		if (!return_is_defined) {
 		if (!return_is_defined) {
 			return lb_arg_type_direct(LLVMVoidTypeInContext(c));
 			return lb_arg_type_direct(LLVMVoidTypeInContext(c));
 		} else if (!is_register(return_type, true)) {
 		} else if (!is_register(return_type, true)) {
@@ -1397,7 +1397,7 @@ namespace lbAbiArm32 {
 };
 };
 
 
 
 
-LB_ABI_INFO(lb_get_abi_info_internal) {
+gb_internal LB_ABI_INFO(lb_get_abi_info_internal) {
 	switch (calling_convention) {
 	switch (calling_convention) {
 	case ProcCC_None:
 	case ProcCC_None:
 	case ProcCC_InlineAsm:
 	case ProcCC_InlineAsm:
@@ -1451,7 +1451,7 @@ LB_ABI_INFO(lb_get_abi_info_internal) {
 }
 }
 
 
 
 
-LB_ABI_INFO(lb_get_abi_info) {
+gb_internal LB_ABI_INFO(lb_get_abi_info) {
 	lbFunctionType *ft = lb_get_abi_info_internal(
 	lbFunctionType *ft = lb_get_abi_info_internal(
 		c,
 		c,
 		arg_types, arg_count,
 		arg_types, arg_count,

+ 130 - 157
src/llvm_backend.cpp

@@ -22,7 +22,7 @@
 #include "llvm_backend_proc.cpp"
 #include "llvm_backend_proc.cpp"
 
 
 
 
-void lb_add_foreign_library_path(lbModule *m, Entity *e) {
+gb_internal void lb_add_foreign_library_path(lbModule *m, Entity *e) {
 	if (e == nullptr) {
 	if (e == nullptr) {
 		return;
 		return;
 	}
 	}
@@ -36,7 +36,7 @@ void lb_add_foreign_library_path(lbModule *m, Entity *e) {
 	mutex_unlock(&m->gen->foreign_mutex);
 	mutex_unlock(&m->gen->foreign_mutex);
 }
 }
 
 
-GB_COMPARE_PROC(foreign_library_cmp) {
+gb_internal GB_COMPARE_PROC(foreign_library_cmp) {
 	int cmp = 0;
 	int cmp = 0;
 	Entity *x = *(Entity **)a;
 	Entity *x = *(Entity **)a;
 	Entity *y = *(Entity **)b;
 	Entity *y = *(Entity **)b;
@@ -78,7 +78,7 @@ GB_COMPARE_PROC(foreign_library_cmp) {
 	return i32_cmp(x->token.pos.offset, y->token.pos.offset);
 	return i32_cmp(x->token.pos.offset, y->token.pos.offset);
 }
 }
 
 
-void lb_set_entity_from_other_modules_linkage_correctly(lbModule *other_module, Entity *e, String const &name) {
+gb_internal void lb_set_entity_from_other_modules_linkage_correctly(lbModule *other_module, Entity *e, String const &name) {
 	if (other_module == nullptr) {
 	if (other_module == nullptr) {
 		return;
 		return;
 	}
 	}
@@ -95,7 +95,7 @@ void lb_set_entity_from_other_modules_linkage_correctly(lbModule *other_module,
 	}
 	}
 }
 }
 
 
-void lb_emit_init_context(lbProcedure *p, lbAddr addr) {
+gb_internal void lb_emit_init_context(lbProcedure *p, lbAddr addr) {
 	GB_ASSERT(addr.kind == lbAddr_Context);
 	GB_ASSERT(addr.kind == lbAddr_Context);
 	GB_ASSERT(addr.ctx.sel.index.count == 0);
 	GB_ASSERT(addr.ctx.sel.index.count == 0);
 
 
@@ -104,7 +104,7 @@ void lb_emit_init_context(lbProcedure *p, lbAddr addr) {
 	lb_emit_runtime_call(p, "__init_context", args);
 	lb_emit_runtime_call(p, "__init_context", args);
 }
 }
 
 
-lbContextData *lb_push_context_onto_stack_from_implicit_parameter(lbProcedure *p) {
+gb_internal lbContextData *lb_push_context_onto_stack_from_implicit_parameter(lbProcedure *p) {
 	Type *pt = base_type(p->type);
 	Type *pt = base_type(p->type);
 	GB_ASSERT(pt->kind == Type_Proc);
 	GB_ASSERT(pt->kind == Type_Proc);
 	GB_ASSERT(pt->Proc.calling_convention == ProcCC_Odin);
 	GB_ASSERT(pt->Proc.calling_convention == ProcCC_Odin);
@@ -131,7 +131,7 @@ lbContextData *lb_push_context_onto_stack_from_implicit_parameter(lbProcedure *p
 	return cd;
 	return cd;
 }
 }
 
 
-lbContextData *lb_push_context_onto_stack(lbProcedure *p, lbAddr ctx) {
+gb_internal lbContextData *lb_push_context_onto_stack(lbProcedure *p, lbAddr ctx) {
 	ctx.kind = lbAddr_Context;
 	ctx.kind = lbAddr_Context;
 	lbContextData *cd = array_add_and_get(&p->context_stack);
 	lbContextData *cd = array_add_and_get(&p->context_stack);
 	cd->ctx = ctx;
 	cd->ctx = ctx;
@@ -140,7 +140,7 @@ lbContextData *lb_push_context_onto_stack(lbProcedure *p, lbAddr ctx) {
 }
 }
 
 
 
 
-lbValue lb_equal_proc_for_type(lbModule *m, Type *type) {
+gb_internal lbValue lb_equal_proc_for_type(lbModule *m, Type *type) {
 	type = base_type(type);
 	type = base_type(type);
 	GB_ASSERT(is_type_comparable(type));
 	GB_ASSERT(is_type_comparable(type));
 
 
@@ -279,7 +279,7 @@ lbValue lb_equal_proc_for_type(lbModule *m, Type *type) {
 	return {compare_proc->value, compare_proc->type};
 	return {compare_proc->value, compare_proc->type};
 }
 }
 
 
-lbValue lb_simple_compare_hash(lbProcedure *p, Type *type, lbValue data, lbValue seed) {
+gb_internal lbValue lb_simple_compare_hash(lbProcedure *p, Type *type, lbValue data, lbValue seed) {
 	GB_ASSERT_MSG(is_type_simple_compare(type), "%s", type_to_string(type));
 	GB_ASSERT_MSG(is_type_simple_compare(type), "%s", type_to_string(type));
 
 
 	auto args = array_make<lbValue>(permanent_allocator(), 3);
 	auto args = array_make<lbValue>(permanent_allocator(), 3);
@@ -289,11 +289,11 @@ lbValue lb_simple_compare_hash(lbProcedure *p, Type *type, lbValue data, lbValue
 	return lb_emit_runtime_call(p, "default_hasher", args);
 	return lb_emit_runtime_call(p, "default_hasher", args);
 }
 }
 
 
-void lb_add_callsite_force_inline(lbProcedure *p, lbValue ret_value) {
+gb_internal void lb_add_callsite_force_inline(lbProcedure *p, lbValue ret_value) {
 	LLVMAddCallSiteAttribute(ret_value.value, LLVMAttributeIndex_FunctionIndex, lb_create_enum_attribute(p->module->ctx, "alwaysinline"));
 	LLVMAddCallSiteAttribute(ret_value.value, LLVMAttributeIndex_FunctionIndex, lb_create_enum_attribute(p->module->ctx, "alwaysinline"));
 }
 }
 
 
-lbValue lb_hasher_proc_for_type(lbModule *m, Type *type) {
+gb_internal lbValue lb_hasher_proc_for_type(lbModule *m, Type *type) {
 	type = core_type(type);
 	type = core_type(type);
 	GB_ASSERT_MSG(is_type_valid_for_keys(type), "%s", type_to_string(type));
 	GB_ASSERT_MSG(is_type_valid_for_keys(type), "%s", type_to_string(type));
 
 
@@ -458,7 +458,7 @@ lbValue lb_hasher_proc_for_type(lbModule *m, Type *type) {
 }
 }
 
 
 
 
-lbValue lb_map_get_proc_for_type(lbModule *m, Type *type) {
+gb_internal lbValue lb_map_get_proc_for_type(lbModule *m, Type *type) {
 	GB_ASSERT(build_context.use_static_map_calls);
 	GB_ASSERT(build_context.use_static_map_calls);
 	type = base_type(type);
 	type = base_type(type);
 	GB_ASSERT(type->kind == Type_Map);
 	GB_ASSERT(type->kind == Type_Map);
@@ -605,13 +605,13 @@ lbValue lb_map_get_proc_for_type(lbModule *m, Type *type) {
 	return {p->value, p->type};
 	return {p->value, p->type};
 }
 }
 
 
-void lb_debug_print(lbProcedure *p, String const &str) {
-	auto args = array_make<lbValue>(heap_allocator(), 1);
-	args[0] = lb_const_string(p->module, str);
-	lb_emit_runtime_call(p, "print_string", args);
-}
+// gb_internal void lb_debug_print(lbProcedure *p, String const &str) {
+// 	auto args = array_make<lbValue>(heap_allocator(), 1);
+// 	args[0] = lb_const_string(p->module, str);
+// 	lb_emit_runtime_call(p, "print_string", args);
+// }
 
 
-lbValue lb_map_set_proc_for_type(lbModule *m, Type *type) {
+gb_internal lbValue lb_map_set_proc_for_type(lbModule *m, Type *type) {
 	GB_ASSERT(build_context.use_static_map_calls);
 	GB_ASSERT(build_context.use_static_map_calls);
 	type = base_type(type);
 	type = base_type(type);
 	GB_ASSERT(type->kind == Type_Map);
 	GB_ASSERT(type->kind == Type_Map);
@@ -731,7 +731,7 @@ lbValue lb_map_set_proc_for_type(lbModule *m, Type *type) {
 }
 }
 
 
 
 
-lbValue lb_generate_anonymous_proc_lit(lbModule *m, String const &prefix_name, Ast *expr, lbProcedure *parent) {
+gb_internal lbValue lb_generate_anonymous_proc_lit(lbModule *m, String const &prefix_name, Ast *expr, lbProcedure *parent) {
 	lbProcedure **found = map_get(&m->gen->anonymous_proc_lits, expr);
 	lbProcedure **found = map_get(&m->gen->anonymous_proc_lits, expr);
 	if (found) {
 	if (found) {
 		return lb_find_procedure_value_from_entity(m, (*found)->entity);
 		return lb_find_procedure_value_from_entity(m, (*found)->entity);
@@ -778,7 +778,7 @@ lbValue lb_generate_anonymous_proc_lit(lbModule *m, String const &prefix_name, A
 }
 }
 
 
 
 
-lbValue lb_gen_map_cell_info_ptr(lbModule *m, Type *type) {
+gb_internal lbValue lb_gen_map_cell_info_ptr(lbModule *m, Type *type) {
 	lbAddr *found = map_get(&m->map_cell_info_map, type);
 	lbAddr *found = map_get(&m->map_cell_info_map, type);
 	if (found) {
 	if (found) {
 		return found->addr;
 		return found->addr;
@@ -802,7 +802,7 @@ lbValue lb_gen_map_cell_info_ptr(lbModule *m, Type *type) {
 
 
 	return addr.addr;
 	return addr.addr;
 }
 }
-lbValue lb_gen_map_info_ptr(lbModule *m, Type *map_type) {
+gb_internal lbValue lb_gen_map_info_ptr(lbModule *m, Type *map_type) {
 	map_type = base_type(map_type);
 	map_type = base_type(map_type);
 	GB_ASSERT(map_type->kind == Type_Map);
 	GB_ASSERT(map_type->kind == Type_Map);
 
 
@@ -833,7 +833,7 @@ lbValue lb_gen_map_info_ptr(lbModule *m, Type *map_type) {
 	return addr.addr;
 	return addr.addr;
 }
 }
 
 
-lbValue lb_const_hash(lbModule *m, lbValue key, Type *key_type) {
+gb_internal lbValue lb_const_hash(lbModule *m, lbValue key, Type *key_type) {
 	if (true) {
 	if (true) {
 		return {};
 		return {};
 	}
 	}
@@ -880,7 +880,7 @@ lbValue lb_const_hash(lbModule *m, lbValue key, Type *key_type) {
 	return hashed_key;
 	return hashed_key;
 }
 }
 
 
-lbValue lb_gen_map_key_hash(lbProcedure *p, lbValue key, Type *key_type, lbValue *key_ptr_) {
+gb_internal lbValue lb_gen_map_key_hash(lbProcedure *p, lbValue key, Type *key_type, lbValue *key_ptr_) {
 	lbValue key_ptr = lb_address_from_load_or_generate_local(p, key);
 	lbValue key_ptr = lb_address_from_load_or_generate_local(p, key);
 	key_ptr = lb_emit_conv(p, key_ptr, t_rawptr);
 	key_ptr = lb_emit_conv(p, key_ptr, t_rawptr);
 
 
@@ -899,7 +899,7 @@ lbValue lb_gen_map_key_hash(lbProcedure *p, lbValue key, Type *key_type, lbValue
 	return hashed_key;
 	return hashed_key;
 }
 }
 
 
-lbValue lb_internal_dynamic_map_get_ptr(lbProcedure *p, lbValue const &map_ptr, lbValue const &key) {
+gb_internal lbValue lb_internal_dynamic_map_get_ptr(lbProcedure *p, lbValue const &map_ptr, lbValue const &key) {
 	Type *map_type = base_type(type_deref(map_ptr.type));
 	Type *map_type = base_type(type_deref(map_ptr.type));
 	GB_ASSERT(map_type->kind == Type_Map);
 	GB_ASSERT(map_type->kind == Type_Map);
 
 
@@ -928,8 +928,8 @@ lbValue lb_internal_dynamic_map_get_ptr(lbProcedure *p, lbValue const &map_ptr,
 	return lb_emit_conv(p, ptr, alloc_type_pointer(map_type->Map.value));
 	return lb_emit_conv(p, ptr, alloc_type_pointer(map_type->Map.value));
 }
 }
 
 
-void lb_internal_dynamic_map_set(lbProcedure *p, lbValue const &map_ptr, Type *map_type,
-                                 lbValue const &map_key, lbValue const &map_value, Ast *node) {
+gb_internal void lb_internal_dynamic_map_set(lbProcedure *p, lbValue const &map_ptr, Type *map_type,
+                                             lbValue const &map_key, lbValue const &map_value, Ast *node) {
 	map_type = base_type(map_type);
 	map_type = base_type(map_type);
 	GB_ASSERT(map_type->kind == Type_Map);
 	GB_ASSERT(map_type->kind == Type_Map);
 
 
@@ -962,7 +962,7 @@ void lb_internal_dynamic_map_set(lbProcedure *p, lbValue const &map_ptr, Type *m
 	}
 	}
 }
 }
 
 
-lbValue lb_dynamic_map_reserve(lbProcedure *p, lbValue const &map_ptr, isize const capacity, TokenPos const &pos) {
+gb_internal lbValue lb_dynamic_map_reserve(lbProcedure *p, lbValue const &map_ptr, isize const capacity, TokenPos const &pos) {
 	GB_ASSERT(!build_context.no_dynamic_literals);
 	GB_ASSERT(!build_context.no_dynamic_literals);
 
 
 	String proc_name = {};
 	String proc_name = {};
@@ -986,7 +986,7 @@ struct lbGlobalVariable {
 	bool is_initialized;
 	bool is_initialized;
 };
 };
 
 
-lbProcedure *lb_create_startup_type_info(lbModule *m) {
+gb_internal lbProcedure *lb_create_startup_type_info(lbModule *m) {
 	if (build_context.disallow_rtti) {
 	if (build_context.disallow_rtti) {
 		return nullptr;
 		return nullptr;
 	}
 	}
@@ -1020,7 +1020,7 @@ lbProcedure *lb_create_startup_type_info(lbModule *m) {
 	return p;
 	return p;
 }
 }
 
 
-lbProcedure *lb_create_objc_names(lbModule *main_module) {
+gb_internal lbProcedure *lb_create_objc_names(lbModule *main_module) {
 	if (build_context.metrics.os != TargetOs_darwin) {
 	if (build_context.metrics.os != TargetOs_darwin) {
 		return nullptr;
 		return nullptr;
 	}
 	}
@@ -1031,7 +1031,7 @@ lbProcedure *lb_create_objc_names(lbModule *main_module) {
 	return p;
 	return p;
 }
 }
 
 
-void lb_finalize_objc_names(lbProcedure *p) {
+gb_internal void lb_finalize_objc_names(lbProcedure *p) {
 	if (p == nullptr) {
 	if (p == nullptr) {
 		return;
 		return;
 	}
 	}
@@ -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);
@@ -1068,7 +1066,7 @@ void lb_finalize_objc_names(lbProcedure *p) {
 
 
 }
 }
 
 
-lbProcedure *lb_create_startup_runtime(lbModule *main_module, lbProcedure *startup_type_info, lbProcedure *objc_names, Array<lbGlobalVariable> &global_variables) { // Startup Runtime
+gb_internal lbProcedure *lb_create_startup_runtime(lbModule *main_module, lbProcedure *startup_type_info, lbProcedure *objc_names, Array<lbGlobalVariable> &global_variables) { // Startup Runtime
 	LLVMPassManagerRef default_function_pass_manager = LLVMCreateFunctionPassManagerForModule(main_module->mod);
 	LLVMPassManagerRef default_function_pass_manager = LLVMCreateFunctionPassManagerForModule(main_module->mod);
 	lb_populate_function_pass_manager(main_module, default_function_pass_manager, false, build_context.optimization_level);
 	lb_populate_function_pass_manager(main_module, default_function_pass_manager, false, build_context.optimization_level);
 	LLVMFinalizeFunctionPassManager(default_function_pass_manager);
 	LLVMFinalizeFunctionPassManager(default_function_pass_manager);
@@ -1088,76 +1086,75 @@ lbProcedure *lb_create_startup_runtime(lbModule *main_module, lbProcedure *start
 		LLVMBuildCall2(p->builder, lb_type_internal_for_procedures_raw(main_module, objc_names->type), objc_names->value, nullptr, 0, "");
 		LLVMBuildCall2(p->builder, lb_type_internal_for_procedures_raw(main_module, objc_names->type), objc_names->value, nullptr, 0, "");
 	}
 	}
 
 
-	for_array(i, global_variables) {
-		auto *var = &global_variables[i];
-		if (var->is_initialized) {
+	for (auto &var : global_variables) {
+		if (var.is_initialized) {
 			continue;
 			continue;
 		}
 		}
 
 
 		lbModule *entity_module = main_module;
 		lbModule *entity_module = main_module;
 
 
-		Entity *e = var->decl->entity;
+		Entity *e = var.decl->entity;
 		GB_ASSERT(e->kind == Entity_Variable);
 		GB_ASSERT(e->kind == Entity_Variable);
 		e->code_gen_module = entity_module;
 		e->code_gen_module = entity_module;
 
 
-		Ast *init_expr = var->decl->init_expr;
+		Ast *init_expr = var.decl->init_expr;
 		if (init_expr != nullptr)  {
 		if (init_expr != nullptr)  {
 			lbValue init = lb_build_expr(p, init_expr);
 			lbValue init = lb_build_expr(p, init_expr);
 			if (init.value == nullptr) {
 			if (init.value == nullptr) {
-				LLVMTypeRef global_type = llvm_addr_type(p->module, var->var);
+				LLVMTypeRef global_type = llvm_addr_type(p->module, var.var);
 				if (is_type_untyped_undef(init.type)) {
 				if (is_type_untyped_undef(init.type)) {
-					// LLVMSetInitializer(var->var.value, LLVMGetUndef(global_type));
-					LLVMSetInitializer(var->var.value, LLVMConstNull(global_type));
-					var->is_initialized = true;
+					// LLVMSetInitializer(var.var.value, LLVMGetUndef(global_type));
+					LLVMSetInitializer(var.var.value, LLVMConstNull(global_type));
+					var.is_initialized = true;
 					continue;
 					continue;
 				} else if (is_type_untyped_nil(init.type)) {
 				} else if (is_type_untyped_nil(init.type)) {
-					LLVMSetInitializer(var->var.value, LLVMConstNull(global_type));
-					var->is_initialized = true;
+					LLVMSetInitializer(var.var.value, LLVMConstNull(global_type));
+					var.is_initialized = true;
 					continue;
 					continue;
 				}
 				}
 				GB_PANIC("Invalid init value, got %s", expr_to_string(init_expr));
 				GB_PANIC("Invalid init value, got %s", expr_to_string(init_expr));
 			}
 			}
 
 
 			if (is_type_any(e->type) || is_type_union(e->type)) {
 			if (is_type_any(e->type) || is_type_union(e->type)) {
-				var->init = init;
+				var.init = init;
 			} else if (lb_is_const_or_global(init)) {
 			} else if (lb_is_const_or_global(init)) {
-				if (!var->is_initialized) {
+				if (!var.is_initialized) {
 					if (is_type_proc(init.type)) {
 					if (is_type_proc(init.type)) {
 						init.value = LLVMConstPointerCast(init.value, lb_type(p->module, init.type));
 						init.value = LLVMConstPointerCast(init.value, lb_type(p->module, init.type));
 					}
 					}
-					LLVMSetInitializer(var->var.value, init.value);
-					var->is_initialized = true;
+					LLVMSetInitializer(var.var.value, init.value);
+					var.is_initialized = true;
 					continue;
 					continue;
 				}
 				}
 			} else {
 			} else {
-				var->init = init;
+				var.init = init;
 			}
 			}
 		}
 		}
 
 
-		if (var->init.value != nullptr) {
-			GB_ASSERT(!var->is_initialized);
-			Type *t = type_deref(var->var.type);
+		if (var.init.value != nullptr) {
+			GB_ASSERT(!var.is_initialized);
+			Type *t = type_deref(var.var.type);
 
 
 			if (is_type_any(t)) {
 			if (is_type_any(t)) {
 				// NOTE(bill): Edge case for 'any' type
 				// NOTE(bill): Edge case for 'any' type
-				Type *var_type = default_type(var->init.type);
-				lbAddr g = lb_add_global_generated(main_module, var_type, var->init);
-				lb_addr_store(p, g, var->init);
+				Type *var_type = default_type(var.init.type);
+				lbAddr g = lb_add_global_generated(main_module, var_type, var.init);
+				lb_addr_store(p, g, var.init);
 				lbValue gp = lb_addr_get_ptr(p, g);
 				lbValue gp = lb_addr_get_ptr(p, g);
 
 
-				lbValue data = lb_emit_struct_ep(p, var->var, 0);
-				lbValue ti   = lb_emit_struct_ep(p, var->var, 1);
+				lbValue data = lb_emit_struct_ep(p, var.var, 0);
+				lbValue ti   = lb_emit_struct_ep(p, var.var, 1);
 				lb_emit_store(p, data, lb_emit_conv(p, gp, t_rawptr));
 				lb_emit_store(p, data, lb_emit_conv(p, gp, t_rawptr));
 				lb_emit_store(p, ti,   lb_type_info(main_module, var_type));
 				lb_emit_store(p, ti,   lb_type_info(main_module, var_type));
 			} else {
 			} else {
-				LLVMTypeRef vt = llvm_addr_type(p->module, var->var);
-				lbValue src0 = lb_emit_conv(p, var->init, t);
+				LLVMTypeRef vt = llvm_addr_type(p->module, var.var);
+				lbValue src0 = lb_emit_conv(p, var.init, t);
 				LLVMValueRef src = OdinLLVMBuildTransmute(p, src0.value, vt);
 				LLVMValueRef src = OdinLLVMBuildTransmute(p, src0.value, vt);
-				LLVMValueRef dst = var->var.value;
+				LLVMValueRef dst = var.var.value;
 				LLVMBuildStore(p->builder, src, dst);
 				LLVMBuildStore(p->builder, src, dst);
 			}
 			}
 
 
-			var->is_initialized = true;
+			var.is_initialized = true;
 		}
 		}
 	}
 	}
 	
 	
@@ -1184,7 +1181,7 @@ lbProcedure *lb_create_startup_runtime(lbModule *main_module, lbProcedure *start
 }
 }
 
 
 
 
-lbProcedure *lb_create_main_procedure(lbModule *m, lbProcedure *startup_runtime) {
+gb_internal lbProcedure *lb_create_main_procedure(lbModule *m, lbProcedure *startup_runtime) {
 	LLVMPassManagerRef default_function_pass_manager = LLVMCreateFunctionPassManagerForModule(m->mod);
 	LLVMPassManagerRef default_function_pass_manager = LLVMCreateFunctionPassManagerForModule(m->mod);
 	lb_populate_function_pass_manager(m, default_function_pass_manager, false, build_context.optimization_level);
 	lb_populate_function_pass_manager(m, default_function_pass_manager, false, build_context.optimization_level);
 	LLVMFinalizeFunctionPassManager(default_function_pass_manager);
 	LLVMFinalizeFunctionPassManager(default_function_pass_manager);
@@ -1255,8 +1252,8 @@ lbProcedure *lb_create_main_procedure(lbModule *m, lbProcedure *startup_runtime)
 		LLVMValueRef indices[2] = {};
 		LLVMValueRef indices[2] = {};
 		indices[0] = LLVMConstInt(lb_type(m, t_i32), 0, false);
 		indices[0] = LLVMConstInt(lb_type(m, t_i32), 0, false);
 
 
-		for_array(i, m->info->testing_procedures) {
-			Entity *testing_proc = m->info->testing_procedures[i];
+		isize testing_proc_index = 0;
+		for (Entity *testing_proc : m->info->testing_procedures) {
 			String name = testing_proc->token.string;
 			String name = testing_proc->token.string;
 
 
 			String pkg_name = {};
 			String pkg_name = {};
@@ -1267,7 +1264,7 @@ lbProcedure *lb_create_main_procedure(lbModule *m, lbProcedure *startup_runtime)
 			lbValue v_name = lb_find_or_add_entity_string(m, name);
 			lbValue v_name = lb_find_or_add_entity_string(m, name);
 			lbValue v_proc = lb_find_procedure_value_from_entity(m, testing_proc);
 			lbValue v_proc = lb_find_procedure_value_from_entity(m, testing_proc);
 
 
-			indices[1] = LLVMConstInt(lb_type(m, t_int), i, false);
+			indices[1] = LLVMConstInt(lb_type(m, t_int), testing_proc_index++, false);
 
 
 			LLVMValueRef vals[3] = {};
 			LLVMValueRef vals[3] = {};
 			vals[0] = v_pkg.value;
 			vals[0] = v_pkg.value;
@@ -1334,7 +1331,7 @@ lbProcedure *lb_create_main_procedure(lbModule *m, lbProcedure *startup_runtime)
 	return p;
 	return p;
 }
 }
 
 
-String lb_filepath_ll_for_module(lbModule *m) {
+gb_internal String lb_filepath_ll_for_module(lbModule *m) {
 	String path = concatenate3_strings(permanent_allocator(),
 	String path = concatenate3_strings(permanent_allocator(),
 		build_context.build_paths[BuildPath_Output].basename,
 		build_context.build_paths[BuildPath_Output].basename,
 		STR_LIT("/"),
 		STR_LIT("/"),
@@ -1350,7 +1347,7 @@ String lb_filepath_ll_for_module(lbModule *m) {
 
 
 	return path;
 	return path;
 }
 }
-String lb_filepath_obj_for_module(lbModule *m) {
+gb_internal String lb_filepath_obj_for_module(lbModule *m) {
 	String path = concatenate3_strings(permanent_allocator(),
 	String path = concatenate3_strings(permanent_allocator(),
 		build_context.build_paths[BuildPath_Output].basename,
 		build_context.build_paths[BuildPath_Output].basename,
 		STR_LIT("/"),
 		STR_LIT("/"),
@@ -1400,7 +1397,7 @@ String lb_filepath_obj_for_module(lbModule *m) {
 }
 }
 
 
 
 
-bool lb_is_module_empty(lbModule *m) {
+gb_internal bool lb_is_module_empty(lbModule *m) {
 	if (LLVMGetFirstFunction(m->mod) == nullptr &&
 	if (LLVMGetFirstFunction(m->mod) == nullptr &&
 	    LLVMGetFirstGlobal(m->mod) == nullptr) {
 	    LLVMGetFirstGlobal(m->mod) == nullptr) {
 		return true;
 		return true;
@@ -1429,7 +1426,7 @@ struct lbLLVMEmitWorker {
 	lbModule *m;
 	lbModule *m;
 };
 };
 
 
-WORKER_TASK_PROC(lb_llvm_emit_worker_proc) {
+gb_internal WORKER_TASK_PROC(lb_llvm_emit_worker_proc) {
 	GB_ASSERT(MULTITHREAD_OBJECT_GENERATION);
 	GB_ASSERT(MULTITHREAD_OBJECT_GENERATION);
 
 
 	char *llvm_error = nullptr;
 	char *llvm_error = nullptr;
@@ -1444,7 +1441,7 @@ WORKER_TASK_PROC(lb_llvm_emit_worker_proc) {
 	return 0;
 	return 0;
 }
 }
 
 
-WORKER_TASK_PROC(lb_llvm_function_pass_worker_proc) {
+gb_internal WORKER_TASK_PROC(lb_llvm_function_pass_worker_proc) {
 	GB_ASSERT(MULTITHREAD_OBJECT_GENERATION);
 	GB_ASSERT(MULTITHREAD_OBJECT_GENERATION);
 
 
 	auto m = cast(lbModule *)data;
 	auto m = cast(lbModule *)data;
@@ -1475,9 +1472,7 @@ WORKER_TASK_PROC(lb_llvm_function_pass_worker_proc) {
 	lb_populate_function_pass_manager(m, default_function_pass_manager_without_memcpy, true, build_context.optimization_level);
 	lb_populate_function_pass_manager(m, default_function_pass_manager_without_memcpy, true, build_context.optimization_level);
 	LLVMFinalizeFunctionPassManager(default_function_pass_manager_without_memcpy);
 	LLVMFinalizeFunctionPassManager(default_function_pass_manager_without_memcpy);
 
 
-
-	for_array(i, m->procedures_to_generate) {
-		lbProcedure *p = m->procedures_to_generate[i];
+	for (lbProcedure *p : m->procedures_to_generate) {
 		if (p->body != nullptr) { // Build Procedure
 		if (p->body != nullptr) { // Build Procedure
 			if (p->flags & lbProcedureFlag_WithoutMemcpyPass) {
 			if (p->flags & lbProcedureFlag_WithoutMemcpyPass) {
 				lb_run_function_pass_manager(default_function_pass_manager_without_memcpy, p);
 				lb_run_function_pass_manager(default_function_pass_manager_without_memcpy, p);
@@ -1505,20 +1500,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);
 	}
 	}
 
 
@@ -1531,7 +1526,7 @@ struct lbLLVMModulePassWorkerData {
 	LLVMTargetMachineRef target_machine;
 	LLVMTargetMachineRef target_machine;
 };
 };
 
 
-WORKER_TASK_PROC(lb_llvm_module_pass_worker_proc) {
+gb_internal WORKER_TASK_PROC(lb_llvm_module_pass_worker_proc) {
 	auto wd = cast(lbLLVMModulePassWorkerData *)data;
 	auto wd = cast(lbLLVMModulePassWorkerData *)data;
 	LLVMPassManagerRef module_pass_manager = LLVMCreatePassManager();
 	LLVMPassManagerRef module_pass_manager = LLVMCreatePassManager();
 	lb_populate_module_pass_manager(wd->target_machine, module_pass_manager, build_context.optimization_level);
 	lb_populate_module_pass_manager(wd->target_machine, module_pass_manager, build_context.optimization_level);
@@ -1540,7 +1535,7 @@ WORKER_TASK_PROC(lb_llvm_module_pass_worker_proc) {
 }
 }
 
 
 
 
-void lb_generate_procedure(lbModule *m, lbProcedure *p) {
+gb_internal void lb_generate_procedure(lbModule *m, lbProcedure *p) {
 	if (p->is_done) {
 	if (p->is_done) {
 		return;
 		return;
 	}
 	}
@@ -1580,7 +1575,7 @@ void lb_generate_procedure(lbModule *m, lbProcedure *p) {
 }
 }
 
 
 
 
-void lb_generate_code(lbGenerator *gen) {
+gb_internal void lb_generate_code(lbGenerator *gen) {
 	TIME_SECTION("LLVM Initializtion");
 	TIME_SECTION("LLVM Initializtion");
 
 
 	isize thread_count = gb_max(build_context.thread_count, 1);
 	isize thread_count = gb_max(build_context.thread_count, 1);
@@ -1636,8 +1631,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 +1696,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,27 +1722,27 @@ void lb_generate_code(lbGenerator *gen) {
 		break;
 		break;
 	}
 	}
 
 
-	for_array(i, gen->modules.entries) {
-		target_machines[i] = LLVMCreateTargetMachine(
+	for (auto const &entry : gen->modules) {
+		LLVMTargetMachineRef 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]));
+		lbModule *m = entry.value;
+		m->target_machine = target_machine;
+		LLVMSetModuleDataLayout(m->mod, LLVMCreateTargetDataLayout(target_machine));
+		array_add(&target_machines, 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;
-				String fullpath = f->fullpath;
-				String filename = remove_directory_from_path(fullpath);
-				String directory = directory_from_path(fullpath);
+			for (auto const &file_entry : info->files) {
+				AstFile *f = file_entry.value;
 				LLVMMetadataRef res = LLVMDIBuilderCreateFile(m->debug_builder,
 				LLVMMetadataRef res = LLVMDIBuilderCreateFile(m->debug_builder,
-					cast(char const *)filename.text, filename.len,
-					cast(char const *)directory.text, directory.len);
+					cast(char const *)f->filename.text, f->filename.len,
+					cast(char const *)f->directory.text, f->directory.len);
 				lb_set_llvm_metadata(m, f, res);
 				lb_set_llvm_metadata(m, f, res);
 			}
 			}
 
 
@@ -1817,9 +1812,7 @@ void lb_generate_code(lbGenerator *gen) {
 			// NOTE(bill): Removes need for heap allocation by making it global memory
 			// NOTE(bill): Removes need for heap allocation by making it global memory
 			isize count = 0;
 			isize count = 0;
 
 
-			for_array(entry_index, m->info->type_info_types) {
-				Type *t = m->info->type_info_types[entry_index];
-
+			for (Type *t : m->info->type_info_types) {
 				isize index = lb_type_info_index(m->info, t, false);
 				isize index = lb_type_info_index(m->info, t, false);
 				if (index < 0) {
 				if (index < 0) {
 					continue;
 					continue;
@@ -1890,8 +1883,7 @@ void lb_generate_code(lbGenerator *gen) {
 	isize global_variable_max_count = 0;
 	isize global_variable_max_count = 0;
 	bool already_has_entry_point = false;
 	bool already_has_entry_point = false;
 
 
-	for_array(i, info->entities) {
-		Entity *e = info->entities[i];
+	for (Entity *e : info->entities) {
 		String name = e->token.string;
 		String name = e->token.string;
 
 
 		if (e->kind == Entity_Variable) {
 		if (e->kind == Entity_Variable) {
@@ -1920,9 +1912,7 @@ void lb_generate_code(lbGenerator *gen) {
 
 
 	auto global_variables = array_make<lbGlobalVariable>(permanent_allocator(), 0, global_variable_max_count);
 	auto global_variables = array_make<lbGlobalVariable>(permanent_allocator(), 0, global_variable_max_count);
 
 
-	for_array(i, info->variable_init_order) {
-		DeclInfo *d = info->variable_init_order[i];
-
+	for (DeclInfo *d : info->variable_init_order) {
 		Entity *e = d->entity;
 		Entity *e = d->entity;
 
 
 		if ((e->scope->flags & ScopeFlag_File) == 0) {
 		if ((e->scope->flags & ScopeFlag_File) == 0) {
@@ -2060,15 +2050,14 @@ 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);
 		}
 		}
 	}
 	}
 
 
 	TIME_SECTION("LLVM Global Procedures and Types");
 	TIME_SECTION("LLVM Global Procedures and Types");
-	for_array(i, info->entities) {
-		Entity *e = info->entities[i];
+	for (Entity *e : info->entities) {
 		String  name  = e->token.string;
 		String  name  = e->token.string;
 		Scope * scope = e->scope;
 		Scope * scope = e->scope;
 
 
@@ -2130,9 +2119,10 @@ 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) {
+	for (auto const &entry : gen->modules) {
+		lbModule *m = entry.value;
+		// NOTE(bill): procedures may be added during generation
+		for (isize i = 0; i < m->procedures_to_generate.count; i++) {
 			lbProcedure *p = m->procedures_to_generate[i];
 			lbProcedure *p = m->procedures_to_generate[i];
 			lb_generate_procedure(m, p);
 			lb_generate_procedure(m, p);
 		}
 		}
@@ -2143,9 +2133,10 @@ 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) {
+	for (auto const &entry : gen->modules) {
+		lbModule *m = entry.value;
+		// NOTE(bill): procedures may be added during generation
+		for (isize i = 0; i < m->missing_procedures_to_check.count; i++) {
 			lbProcedure *p = m->missing_procedures_to_check[i];
 			lbProcedure *p = m->missing_procedures_to_check[i];
 			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 +2146,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 +2159,21 @@ 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 +2188,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,9 +2210,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,8 +2233,8 @@ 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 (auto const &entry : gen->modules) {
+		lbModule *m = entry.value;
 		for_array(i, m->info->required_foreign_imports_through_force) {
 		for_array(i, m->info->required_foreign_imports_through_force) {
 			Entity *e = m->info->required_foreign_imports_through_force[i];
 			Entity *e = m->info->required_foreign_imports_through_force[i];
 			lb_add_foreign_library_path(m, e);
 			lb_add_foreign_library_path(m, e);
@@ -2275,16 +2248,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 +2268,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 +2277,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 +2292,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;

+ 138 - 137
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
@@ -321,197 +322,197 @@ struct lbProcedure {
 #define LLVMBuildPtrDiff2(Builder__, Ty__, LHS__, RHS__, Name__) LLVMBuildPtrDiff(Builder__, LHS__, RHS__, Name__)
 #define LLVMBuildPtrDiff2(Builder__, Ty__, LHS__, RHS__, Name__) LLVMBuildPtrDiff(Builder__, LHS__, RHS__, Name__)
 #endif
 #endif
 
 
-bool lb_init_generator(lbGenerator *gen, Checker *c);
+gb_internal bool lb_init_generator(lbGenerator *gen, Checker *c);
 
 
-String lb_mangle_name(lbModule *m, Entity *e);
-String lb_get_entity_name(lbModule *m, Entity *e, String name = {});
+gb_internal String lb_mangle_name(lbModule *m, Entity *e);
+gb_internal String lb_get_entity_name(lbModule *m, Entity *e, String name = {});
 
 
-LLVMAttributeRef lb_create_enum_attribute(LLVMContextRef ctx, char const *name, u64 value=0);
-LLVMAttributeRef lb_create_enum_attribute_with_type(LLVMContextRef ctx, char const *name, LLVMTypeRef type);
-void lb_add_proc_attribute_at_index(lbProcedure *p, isize index, char const *name, u64 value);
-void lb_add_proc_attribute_at_index(lbProcedure *p, isize index, char const *name);
-lbProcedure *lb_create_procedure(lbModule *module, Entity *entity, bool ignore_body=false);
-void lb_end_procedure(lbProcedure *p);
+gb_internal LLVMAttributeRef lb_create_enum_attribute(LLVMContextRef ctx, char const *name, u64 value=0);
+gb_internal LLVMAttributeRef lb_create_enum_attribute_with_type(LLVMContextRef ctx, char const *name, LLVMTypeRef type);
+gb_internal void lb_add_proc_attribute_at_index(lbProcedure *p, isize index, char const *name, u64 value);
+gb_internal void lb_add_proc_attribute_at_index(lbProcedure *p, isize index, char const *name);
+gb_internal lbProcedure *lb_create_procedure(lbModule *module, Entity *entity, bool ignore_body=false);
+gb_internal void lb_end_procedure(lbProcedure *p);
 
 
 
 
-LLVMTypeRef lb_type(lbModule *m, Type *type);
-LLVMTypeRef llvm_get_element_type(LLVMTypeRef type);
+gb_internal LLVMTypeRef lb_type(lbModule *m, Type *type);
+gb_internal LLVMTypeRef llvm_get_element_type(LLVMTypeRef type);
 
 
-lbBlock *lb_create_block(lbProcedure *p, char const *name, bool append=false);
+gb_internal lbBlock *lb_create_block(lbProcedure *p, char const *name, bool append=false);
 
 
-lbValue lb_const_nil(lbModule *m, Type *type);
-lbValue lb_const_undef(lbModule *m, Type *type);
-lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_local=true);
-lbValue lb_const_bool(lbModule *m, Type *type, bool value);
-lbValue lb_const_int(lbModule *m, Type *type, u64 value);
+gb_internal lbValue lb_const_nil(lbModule *m, Type *type);
+gb_internal lbValue lb_const_undef(lbModule *m, Type *type);
+gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_local=true);
+gb_internal lbValue lb_const_bool(lbModule *m, Type *type, bool value);
+gb_internal lbValue lb_const_int(lbModule *m, Type *type, u64 value);
 
 
 
 
-lbAddr lb_addr(lbValue addr);
-Type *lb_addr_type(lbAddr const &addr);
-LLVMTypeRef llvm_addr_type(lbModule *module, lbValue addr_val);
-void lb_addr_store(lbProcedure *p, lbAddr addr, lbValue value);
-lbValue lb_addr_load(lbProcedure *p, lbAddr const &addr);
-lbValue lb_emit_load(lbProcedure *p, lbValue v);
-void lb_emit_store(lbProcedure *p, lbValue ptr, lbValue value);
+gb_internal lbAddr lb_addr(lbValue addr);
+gb_internal Type *lb_addr_type(lbAddr const &addr);
+gb_internal LLVMTypeRef llvm_addr_type(lbModule *module, lbValue addr_val);
+gb_internal void lb_addr_store(lbProcedure *p, lbAddr addr, lbValue value);
+gb_internal lbValue lb_addr_load(lbProcedure *p, lbAddr const &addr);
+gb_internal lbValue lb_emit_load(lbProcedure *p, lbValue v);
+gb_internal void lb_emit_store(lbProcedure *p, lbValue ptr, lbValue value);
 
 
 
 
-void    lb_build_stmt(lbProcedure *p, Ast *stmt);
-lbValue lb_build_expr(lbProcedure *p, Ast *expr);
-lbAddr  lb_build_addr(lbProcedure *p, Ast *expr);
-void lb_build_stmt_list(lbProcedure *p, Array<Ast *> const &stmts);
+gb_internal void    lb_build_stmt(lbProcedure *p, Ast *stmt);
+gb_internal lbValue lb_build_expr(lbProcedure *p, Ast *expr);
+gb_internal lbAddr  lb_build_addr(lbProcedure *p, Ast *expr);
+gb_internal void lb_build_stmt_list(lbProcedure *p, Array<Ast *> const &stmts);
 
 
-lbValue lb_emit_epi(lbProcedure *p, lbValue const &value, isize index);
-lbValue lb_emit_epi(lbModule *m, lbValue const &value, isize index);
-lbValue lb_emit_array_epi(lbModule *m, lbValue s, isize index);
-lbValue lb_emit_struct_ep(lbProcedure *p, lbValue s, i32 index);
-lbValue lb_emit_struct_ev(lbProcedure *p, lbValue s, i32 index);
-lbValue lb_emit_tuple_ev(lbProcedure *p, lbValue value, i32 index);
-lbValue lb_emit_array_epi(lbProcedure *p, lbValue value, isize index);
-lbValue lb_emit_array_ep(lbProcedure *p, lbValue s, lbValue index);
-lbValue lb_emit_deep_field_gep(lbProcedure *p, lbValue e, Selection sel);
-lbValue lb_emit_deep_field_ev(lbProcedure *p, lbValue e, Selection sel);
+gb_internal lbValue lb_emit_epi(lbProcedure *p, lbValue const &value, isize index);
+gb_internal lbValue lb_emit_epi(lbModule *m, lbValue const &value, isize index);
+gb_internal lbValue lb_emit_array_epi(lbModule *m, lbValue s, isize index);
+gb_internal lbValue lb_emit_struct_ep(lbProcedure *p, lbValue s, i32 index);
+gb_internal lbValue lb_emit_struct_ev(lbProcedure *p, lbValue s, i32 index);
+gb_internal lbValue lb_emit_tuple_ev(lbProcedure *p, lbValue value, i32 index);
+gb_internal lbValue lb_emit_array_epi(lbProcedure *p, lbValue value, isize index);
+gb_internal lbValue lb_emit_array_ep(lbProcedure *p, lbValue s, lbValue index);
+gb_internal lbValue lb_emit_deep_field_gep(lbProcedure *p, lbValue e, Selection sel);
+gb_internal lbValue lb_emit_deep_field_ev(lbProcedure *p, lbValue e, Selection sel);
 
 
-lbValue lb_emit_matrix_ep(lbProcedure *p, lbValue s, lbValue row, lbValue column);
-lbValue lb_emit_matrix_epi(lbProcedure *p, lbValue s, isize row, isize column);
-lbValue lb_emit_matrix_ev(lbProcedure *p, lbValue s, isize row, isize column);
+gb_internal lbValue lb_emit_matrix_ep(lbProcedure *p, lbValue s, lbValue row, lbValue column);
+gb_internal lbValue lb_emit_matrix_epi(lbProcedure *p, lbValue s, isize row, isize column);
+gb_internal lbValue lb_emit_matrix_ev(lbProcedure *p, lbValue s, isize row, isize column);
 
 
 
 
-lbValue lb_emit_arith(lbProcedure *p, TokenKind op, lbValue lhs, lbValue rhs, Type *type);
-lbValue lb_emit_byte_swap(lbProcedure *p, lbValue value, Type *end_type);
-void lb_emit_defer_stmts(lbProcedure *p, lbDeferExitKind kind, lbBlock *block);
-lbValue lb_emit_transmute(lbProcedure *p, lbValue value, Type *t);
-lbValue lb_emit_comp(lbProcedure *p, TokenKind op_kind, lbValue left, lbValue right);
-lbValue lb_emit_call(lbProcedure *p, lbValue value, Array<lbValue> const &args, ProcInlining inlining = ProcInlining_none);
-lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t);
-lbValue lb_emit_comp_against_nil(lbProcedure *p, TokenKind op_kind, lbValue x);
+gb_internal lbValue lb_emit_arith(lbProcedure *p, TokenKind op, lbValue lhs, lbValue rhs, Type *type);
+gb_internal lbValue lb_emit_byte_swap(lbProcedure *p, lbValue value, Type *end_type);
+gb_internal void lb_emit_defer_stmts(lbProcedure *p, lbDeferExitKind kind, lbBlock *block);
+gb_internal lbValue lb_emit_transmute(lbProcedure *p, lbValue value, Type *t);
+gb_internal lbValue lb_emit_comp(lbProcedure *p, TokenKind op_kind, lbValue left, lbValue right);
+gb_internal lbValue lb_emit_call(lbProcedure *p, lbValue value, Array<lbValue> const &args, ProcInlining inlining = ProcInlining_none);
+gb_internal lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t);
+gb_internal lbValue lb_emit_comp_against_nil(lbProcedure *p, TokenKind op_kind, lbValue x);
 
 
-void lb_emit_jump(lbProcedure *p, lbBlock *target_block);
-void lb_emit_if(lbProcedure *p, lbValue cond, lbBlock *true_block, lbBlock *false_block);
-void lb_start_block(lbProcedure *p, lbBlock *b);
+gb_internal void lb_emit_jump(lbProcedure *p, lbBlock *target_block);
+gb_internal void lb_emit_if(lbProcedure *p, lbValue cond, lbBlock *true_block, lbBlock *false_block);
+gb_internal void lb_start_block(lbProcedure *p, lbBlock *b);
 
 
-lbValue lb_build_call_expr(lbProcedure *p, Ast *expr);
+gb_internal lbValue lb_build_call_expr(lbProcedure *p, Ast *expr);
 
 
 
 
-lbAddr lb_find_or_generate_context_ptr(lbProcedure *p);
-lbContextData *lb_push_context_onto_stack(lbProcedure *p, lbAddr ctx);
-lbContextData *lb_push_context_onto_stack_from_implicit_parameter(lbProcedure *p);
+gb_internal lbAddr lb_find_or_generate_context_ptr(lbProcedure *p);
+gb_internal lbContextData *lb_push_context_onto_stack(lbProcedure *p, lbAddr ctx);
+gb_internal lbContextData *lb_push_context_onto_stack_from_implicit_parameter(lbProcedure *p);
 
 
 
 
-lbAddr lb_add_global_generated(lbModule *m, Type *type, lbValue value={}, Entity **entity_=nullptr);
-lbAddr lb_add_local(lbProcedure *p, Type *type, Entity *e=nullptr, bool zero_init=true, bool force_no_init=false);
+gb_internal lbAddr lb_add_global_generated(lbModule *m, Type *type, lbValue value={}, Entity **entity_=nullptr);
+gb_internal lbAddr lb_add_local(lbProcedure *p, Type *type, Entity *e=nullptr, bool zero_init=true, bool force_no_init=false);
 
 
-void lb_add_foreign_library_path(lbModule *m, Entity *e);
+gb_internal void lb_add_foreign_library_path(lbModule *m, Entity *e);
 
 
-lbValue lb_typeid(lbModule *m, Type *type);
+gb_internal lbValue lb_typeid(lbModule *m, Type *type);
 
 
-lbValue lb_address_from_load_or_generate_local(lbProcedure *p, lbValue value);
-lbValue lb_address_from_load(lbProcedure *p, lbValue value);
-void    lb_add_defer_node(lbProcedure *p, isize scope_index, Ast *stmt);
-lbAddr lb_add_local_generated(lbProcedure *p, Type *type, bool zero_init);
+gb_internal lbValue lb_address_from_load_or_generate_local(lbProcedure *p, lbValue value);
+gb_internal lbValue lb_address_from_load(lbProcedure *p, lbValue value);
+gb_internal void    lb_add_defer_node(lbProcedure *p, isize scope_index, Ast *stmt);
+gb_internal lbAddr lb_add_local_generated(lbProcedure *p, Type *type, bool zero_init);
 
 
-lbValue lb_emit_runtime_call(lbProcedure *p, char const *c_name, Array<lbValue> const &args);
+gb_internal lbValue lb_emit_runtime_call(lbProcedure *p, char const *c_name, Array<lbValue> const &args);
 
 
 
 
-lbValue lb_emit_ptr_offset(lbProcedure *p, lbValue ptr, lbValue index);
-lbValue lb_string_elem(lbProcedure *p, lbValue string);
-lbValue lb_string_len(lbProcedure *p, lbValue string);
-lbValue lb_cstring_len(lbProcedure *p, lbValue value);
-lbValue lb_array_elem(lbProcedure *p, lbValue array_ptr);
-lbValue lb_slice_elem(lbProcedure *p, lbValue slice);
-lbValue lb_slice_len(lbProcedure *p, lbValue slice);
-lbValue lb_dynamic_array_elem(lbProcedure *p, lbValue da);
-lbValue lb_dynamic_array_len(lbProcedure *p, lbValue da);
-lbValue lb_dynamic_array_cap(lbProcedure *p, lbValue da);
-lbValue lb_dynamic_array_allocator(lbProcedure *p, lbValue da);
-lbValue lb_map_len(lbProcedure *p, lbValue value);
-lbValue lb_map_cap(lbProcedure *p, lbValue value);
-lbValue lb_soa_struct_len(lbProcedure *p, lbValue value);
-void lb_emit_increment(lbProcedure *p, lbValue addr);
-lbValue lb_emit_select(lbProcedure *p, lbValue cond, lbValue x, lbValue y);
+gb_internal lbValue lb_emit_ptr_offset(lbProcedure *p, lbValue ptr, lbValue index);
+gb_internal lbValue lb_string_elem(lbProcedure *p, lbValue string);
+gb_internal lbValue lb_string_len(lbProcedure *p, lbValue string);
+gb_internal lbValue lb_cstring_len(lbProcedure *p, lbValue value);
+gb_internal lbValue lb_array_elem(lbProcedure *p, lbValue array_ptr);
+gb_internal lbValue lb_slice_elem(lbProcedure *p, lbValue slice);
+gb_internal lbValue lb_slice_len(lbProcedure *p, lbValue slice);
+gb_internal lbValue lb_dynamic_array_elem(lbProcedure *p, lbValue da);
+gb_internal lbValue lb_dynamic_array_len(lbProcedure *p, lbValue da);
+gb_internal lbValue lb_dynamic_array_cap(lbProcedure *p, lbValue da);
+gb_internal lbValue lb_dynamic_array_allocator(lbProcedure *p, lbValue da);
+gb_internal lbValue lb_map_len(lbProcedure *p, lbValue value);
+gb_internal lbValue lb_map_cap(lbProcedure *p, lbValue value);
+gb_internal lbValue lb_soa_struct_len(lbProcedure *p, lbValue value);
+gb_internal void lb_emit_increment(lbProcedure *p, lbValue addr);
+gb_internal lbValue lb_emit_select(lbProcedure *p, lbValue cond, lbValue x, lbValue y);
 
 
-lbValue lb_emit_mul_add(lbProcedure *p, lbValue a, lbValue b, lbValue c, Type *t);
+gb_internal lbValue lb_emit_mul_add(lbProcedure *p, lbValue a, lbValue b, lbValue c, Type *t);
 
 
-void lb_fill_slice(lbProcedure *p, lbAddr const &slice, lbValue base_elem, lbValue len);
+gb_internal void lb_fill_slice(lbProcedure *p, lbAddr const &slice, lbValue base_elem, lbValue len);
 
 
-lbValue lb_type_info(lbModule *m, Type *type);
+gb_internal lbValue lb_type_info(lbModule *m, Type *type);
 
 
-lbValue lb_find_or_add_entity_string(lbModule *m, String const &str);
-lbValue lb_generate_anonymous_proc_lit(lbModule *m, String const &prefix_name, Ast *expr, lbProcedure *parent = nullptr);
+gb_internal lbValue lb_find_or_add_entity_string(lbModule *m, String const &str);
+gb_internal lbValue lb_generate_anonymous_proc_lit(lbModule *m, String const &prefix_name, Ast *expr, lbProcedure *parent = nullptr);
 
 
-bool lb_is_const(lbValue value);
-bool lb_is_const_or_global(lbValue value);
-bool lb_is_const_nil(lbValue value);
-String lb_get_const_string(lbModule *m, lbValue value);
+gb_internal bool lb_is_const(lbValue value);
+gb_internal bool lb_is_const_or_global(lbValue value);
+gb_internal bool lb_is_const_nil(lbValue value);
+gb_internal String lb_get_const_string(lbModule *m, lbValue value);
 
 
-lbValue lb_generate_local_array(lbProcedure *p, Type *elem_type, i64 count, bool zero_init=true);
-lbValue lb_generate_global_array(lbModule *m, Type *elem_type, i64 count, String prefix, i64 id);
-lbValue lb_gen_map_key_hash(lbProcedure *p, lbValue key, Type *key_type, lbValue *key_ptr_);
-lbValue lb_gen_map_cell_info_ptr(lbModule *m, Type *type);
-lbValue lb_gen_map_info_ptr(lbModule *m, Type *map_type);
+gb_internal lbValue lb_generate_local_array(lbProcedure *p, Type *elem_type, i64 count, bool zero_init=true);
+gb_internal lbValue lb_generate_global_array(lbModule *m, Type *elem_type, i64 count, String prefix, i64 id);
+gb_internal lbValue lb_gen_map_key_hash(lbProcedure *p, lbValue key, Type *key_type, lbValue *key_ptr_);
+gb_internal lbValue lb_gen_map_cell_info_ptr(lbModule *m, Type *type);
+gb_internal lbValue lb_gen_map_info_ptr(lbModule *m, Type *map_type);
 
 
-lbValue lb_internal_dynamic_map_get_ptr(lbProcedure *p, lbValue const &map_ptr, lbValue const &key);
-void    lb_internal_dynamic_map_set(lbProcedure *p, lbValue const &map_ptr, Type *map_type, lbValue const &map_key, lbValue const &map_value, Ast *node);
-lbValue lb_dynamic_map_reserve(lbProcedure *p, lbValue const &map_ptr, isize const capacity, TokenPos const &pos);
+gb_internal lbValue lb_internal_dynamic_map_get_ptr(lbProcedure *p, lbValue const &map_ptr, lbValue const &key);
+gb_internal void    lb_internal_dynamic_map_set(lbProcedure *p, lbValue const &map_ptr, Type *map_type, lbValue const &map_key, lbValue const &map_value, Ast *node);
+gb_internal lbValue lb_dynamic_map_reserve(lbProcedure *p, lbValue const &map_ptr, isize const capacity, TokenPos const &pos);
 
 
-lbValue lb_find_procedure_value_from_entity(lbModule *m, Entity *e);
-lbValue lb_find_value_from_entity(lbModule *m, Entity *e);
+gb_internal lbValue lb_find_procedure_value_from_entity(lbModule *m, Entity *e);
+gb_internal lbValue lb_find_value_from_entity(lbModule *m, Entity *e);
 
 
-void lb_store_type_case_implicit(lbProcedure *p, Ast *clause, lbValue value);
-lbAddr lb_store_range_stmt_val(lbProcedure *p, Ast *stmt_val, lbValue value);
-lbValue lb_emit_source_code_location_const(lbProcedure *p, String const &procedure, TokenPos const &pos);
+gb_internal void lb_store_type_case_implicit(lbProcedure *p, Ast *clause, lbValue value);
+gb_internal lbAddr lb_store_range_stmt_val(lbProcedure *p, Ast *stmt_val, lbValue value);
+gb_internal lbValue lb_emit_source_code_location_const(lbProcedure *p, String const &procedure, TokenPos const &pos);
 
 
-lbValue lb_handle_param_value(lbProcedure *p, Type *parameter_type, ParameterValue const &param_value, TokenPos const &pos);
+gb_internal lbValue lb_handle_param_value(lbProcedure *p, Type *parameter_type, ParameterValue const &param_value, TokenPos const &pos);
 
 
-lbValue lb_equal_proc_for_type(lbModule *m, Type *type);
-lbValue lb_hasher_proc_for_type(lbModule *m, Type *type);
-lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t);
+gb_internal lbValue lb_equal_proc_for_type(lbModule *m, Type *type);
+gb_internal lbValue lb_hasher_proc_for_type(lbModule *m, Type *type);
+gb_internal lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t);
 
 
-LLVMMetadataRef lb_debug_type(lbModule *m, Type *type);
+gb_internal LLVMMetadataRef lb_debug_type(lbModule *m, Type *type);
 
 
-lbValue lb_emit_count_ones(lbProcedure *p, lbValue x, Type *type);
-lbValue lb_emit_count_zeros(lbProcedure *p, lbValue x, Type *type);
-lbValue lb_emit_count_trailing_zeros(lbProcedure *p, lbValue x, Type *type);
-lbValue lb_emit_count_leading_zeros(lbProcedure *p, lbValue x, Type *type);
-lbValue lb_emit_reverse_bits(lbProcedure *p, lbValue x, Type *type);
+gb_internal lbValue lb_emit_count_ones(lbProcedure *p, lbValue x, Type *type);
+gb_internal lbValue lb_emit_count_zeros(lbProcedure *p, lbValue x, Type *type);
+gb_internal lbValue lb_emit_count_trailing_zeros(lbProcedure *p, lbValue x, Type *type);
+gb_internal lbValue lb_emit_count_leading_zeros(lbProcedure *p, lbValue x, Type *type);
+gb_internal lbValue lb_emit_reverse_bits(lbProcedure *p, lbValue x, Type *type);
 
 
-lbValue lb_emit_bit_set_card(lbProcedure *p, lbValue x);
+gb_internal lbValue lb_emit_bit_set_card(lbProcedure *p, lbValue x);
 
 
-void lb_mem_zero_addr(lbProcedure *p, LLVMValueRef ptr, Type *type);
+gb_internal void lb_mem_zero_addr(lbProcedure *p, LLVMValueRef ptr, Type *type);
 
 
-void lb_build_nested_proc(lbProcedure *p, AstProcLit *pd, Entity *e);
-lbValue lb_emit_logical_binary_expr(lbProcedure *p, TokenKind op, Ast *left, Ast *right, Type *type);
-lbValue lb_build_cond(lbProcedure *p, Ast *cond, lbBlock *true_block, lbBlock *false_block);
+gb_internal void lb_build_nested_proc(lbProcedure *p, AstProcLit *pd, Entity *e);
+gb_internal lbValue lb_emit_logical_binary_expr(lbProcedure *p, TokenKind op, Ast *left, Ast *right, Type *type);
+gb_internal lbValue lb_build_cond(lbProcedure *p, Ast *cond, lbBlock *true_block, lbBlock *false_block);
 
 
-LLVMValueRef llvm_const_named_struct(lbModule *m, Type *t, LLVMValueRef *values, isize value_count_);
-LLVMValueRef llvm_const_named_struct_internal(LLVMTypeRef t, LLVMValueRef *values, isize value_count_);
-void lb_set_entity_from_other_modules_linkage_correctly(lbModule *other_module, Entity *e, String const &name);
+gb_internal LLVMValueRef llvm_const_named_struct(lbModule *m, Type *t, LLVMValueRef *values, isize value_count_);
+gb_internal LLVMValueRef llvm_const_named_struct_internal(LLVMTypeRef t, LLVMValueRef *values, isize value_count_);
+gb_internal void lb_set_entity_from_other_modules_linkage_correctly(lbModule *other_module, Entity *e, String const &name);
 
 
-lbValue lb_expr_untyped_const_to_typed(lbModule *m, Ast *expr, Type *t);
-bool lb_is_expr_untyped_const(Ast *expr);
+gb_internal lbValue lb_expr_untyped_const_to_typed(lbModule *m, Ast *expr, Type *t);
+gb_internal bool lb_is_expr_untyped_const(Ast *expr);
 
 
-LLVMValueRef llvm_alloca(lbProcedure *p, LLVMTypeRef llvm_type, isize alignment, char const *name = "");
+gb_internal LLVMValueRef llvm_alloca(lbProcedure *p, LLVMTypeRef llvm_type, isize alignment, char const *name = "");
 
 
-void lb_mem_zero_ptr(lbProcedure *p, LLVMValueRef ptr, Type *type, unsigned alignment);
+gb_internal void lb_mem_zero_ptr(lbProcedure *p, LLVMValueRef ptr, Type *type, unsigned alignment);
 
 
-void lb_emit_init_context(lbProcedure *p, lbAddr addr);
+gb_internal void lb_emit_init_context(lbProcedure *p, lbAddr addr);
 
 
 
 
-lbStructFieldRemapping lb_get_struct_remapping(lbModule *m, Type *t);
-LLVMTypeRef lb_type_padding_filler(lbModule *m, i64 padding, i64 padding_align);
+gb_internal lbStructFieldRemapping lb_get_struct_remapping(lbModule *m, Type *t);
+gb_internal LLVMTypeRef lb_type_padding_filler(lbModule *m, i64 padding, i64 padding_align);
 
 
-LLVMValueRef llvm_basic_shuffle(lbProcedure *p, LLVMValueRef vector, LLVMValueRef mask);
+gb_internal LLVMValueRef llvm_basic_shuffle(lbProcedure *p, LLVMValueRef vector, LLVMValueRef mask);
 
 
-LLVMValueRef lb_call_intrinsic(lbProcedure *p, const char *name, LLVMValueRef* args, unsigned arg_count, LLVMTypeRef* types, unsigned type_count);
-void lb_mem_copy_overlapping(lbProcedure *p, lbValue dst, lbValue src, lbValue len, bool is_volatile=false);
-void lb_mem_copy_non_overlapping(lbProcedure *p, lbValue dst, lbValue src, lbValue len, bool is_volatile=false);
-LLVMValueRef lb_mem_zero_ptr_internal(lbProcedure *p, LLVMValueRef ptr, LLVMValueRef len, unsigned alignment, bool is_volatile);
+gb_internal LLVMValueRef lb_call_intrinsic(lbProcedure *p, const char *name, LLVMValueRef* args, unsigned arg_count, LLVMTypeRef* types, unsigned type_count);
+gb_internal void lb_mem_copy_overlapping(lbProcedure *p, lbValue dst, lbValue src, lbValue len, bool is_volatile=false);
+gb_internal void lb_mem_copy_non_overlapping(lbProcedure *p, lbValue dst, lbValue src, lbValue len, bool is_volatile=false);
+gb_internal LLVMValueRef lb_mem_zero_ptr_internal(lbProcedure *p, LLVMValueRef ptr, LLVMValueRef len, unsigned alignment, bool is_volatile);
 
 
-i64 lb_max_zero_init_size(void) {
+gb_internal gb_inline i64 lb_max_zero_init_size(void) {
 	return cast(i64)(4*build_context.word_size);
 	return cast(i64)(4*build_context.word_size);
 }
 }
 
 
-LLVMTypeRef OdinLLVMGetArrayElementType(LLVMTypeRef type);
-LLVMTypeRef OdinLLVMGetVectorElementType(LLVMTypeRef type);
+gb_internal LLVMTypeRef OdinLLVMGetArrayElementType(LLVMTypeRef type);
+gb_internal LLVMTypeRef OdinLLVMGetVectorElementType(LLVMTypeRef type);
 
 
 #define LB_STARTUP_RUNTIME_PROC_NAME   "__$startup_runtime"
 #define LB_STARTUP_RUNTIME_PROC_NAME   "__$startup_runtime"
 #define LB_STARTUP_TYPE_INFO_PROC_NAME "__$startup_type_info"
 #define LB_STARTUP_TYPE_INFO_PROC_NAME "__$startup_type_info"
@@ -631,7 +632,7 @@ enum : LLVMAttributeIndex {
 };
 };
 
 
 
 
-char const *llvm_linkage_strings[] = {
+gb_global char const *llvm_linkage_strings[] = {
 	"external linkage",
 	"external linkage",
 	"available externally linkage",
 	"available externally linkage",
 	"link once any linkage",
 	"link once any linkage",

+ 30 - 30
src/llvm_backend_const.cpp

@@ -1,4 +1,4 @@
-bool lb_is_const(lbValue value) {
+gb_internal bool lb_is_const(lbValue value) {
 	LLVMValueRef v = value.value;
 	LLVMValueRef v = value.value;
 	if (is_type_untyped_nil(value.type) || is_type_untyped_undef(value.type)) {
 	if (is_type_untyped_nil(value.type) || is_type_untyped_undef(value.type)) {
 		// TODO(bill): Is this correct behaviour?
 		// TODO(bill): Is this correct behaviour?
@@ -10,7 +10,7 @@ bool lb_is_const(lbValue value) {
 	return false;
 	return false;
 }
 }
 
 
-bool lb_is_const_or_global(lbValue value) {
+gb_internal bool lb_is_const_or_global(lbValue value) {
 	if (lb_is_const(value)) {
 	if (lb_is_const(value)) {
 		return true;
 		return true;
 	}
 	}
@@ -29,7 +29,7 @@ bool lb_is_const_or_global(lbValue value) {
 }
 }
 
 
 
 
-bool lb_is_elem_const(Ast *elem, Type *elem_type) {
+gb_internal bool lb_is_elem_const(Ast *elem, Type *elem_type) {
 	if (!elem_type_can_be_constant(elem_type)) {
 	if (!elem_type_can_be_constant(elem_type)) {
 		return false;
 		return false;
 	}
 	}
@@ -42,7 +42,7 @@ bool lb_is_elem_const(Ast *elem, Type *elem_type) {
 }
 }
 
 
 
 
-bool lb_is_const_nil(lbValue value) {
+gb_internal bool lb_is_const_nil(lbValue value) {
 	LLVMValueRef v = value.value;
 	LLVMValueRef v = value.value;
 	if (LLVMIsConstant(v)) {
 	if (LLVMIsConstant(v)) {
 		if (LLVMIsAConstantAggregateZero(v)) {
 		if (LLVMIsAConstantAggregateZero(v)) {
@@ -55,7 +55,7 @@ bool lb_is_const_nil(lbValue value) {
 }
 }
 
 
 
 
-bool lb_is_expr_constant_zero(Ast *expr) {
+gb_internal bool lb_is_expr_constant_zero(Ast *expr) {
 	GB_ASSERT(expr != nullptr);
 	GB_ASSERT(expr != nullptr);
 	auto v = exact_value_to_integer(expr->tav.value);
 	auto v = exact_value_to_integer(expr->tav.value);
 	if (v.kind == ExactValue_Integer) {
 	if (v.kind == ExactValue_Integer) {
@@ -64,7 +64,7 @@ bool lb_is_expr_constant_zero(Ast *expr) {
 	return false;
 	return false;
 }
 }
 
 
-String lb_get_const_string(lbModule *m, lbValue value) {
+gb_internal String lb_get_const_string(lbModule *m, lbValue value) {
 	GB_ASSERT(lb_is_const(value));
 	GB_ASSERT(lb_is_const(value));
 	GB_ASSERT(LLVMIsConstant(value.value));
 	GB_ASSERT(LLVMIsConstant(value.value));
 
 
@@ -92,7 +92,7 @@ String lb_get_const_string(lbModule *m, lbValue value) {
 }
 }
 
 
 
 
-LLVMValueRef llvm_const_cast(LLVMValueRef val, LLVMTypeRef dst) {
+gb_internal LLVMValueRef llvm_const_cast(LLVMValueRef val, LLVMTypeRef dst) {
 	LLVMTypeRef src = LLVMTypeOf(val);
 	LLVMTypeRef src = LLVMTypeOf(val);
 	if (src == dst) {
 	if (src == dst) {
 		return val;
 		return val;
@@ -116,7 +116,7 @@ LLVMValueRef llvm_const_cast(LLVMValueRef val, LLVMTypeRef dst) {
 }
 }
 
 
 
 
-lbValue lb_const_ptr_cast(lbModule *m, lbValue value, Type *t) {
+gb_internal lbValue lb_const_ptr_cast(lbModule *m, lbValue value, Type *t) {
 	GB_ASSERT(is_type_internally_pointer_like(value.type));
 	GB_ASSERT(is_type_internally_pointer_like(value.type));
 	GB_ASSERT(is_type_internally_pointer_like(t));
 	GB_ASSERT(is_type_internally_pointer_like(t));
 	GB_ASSERT(lb_is_const(value));
 	GB_ASSERT(lb_is_const(value));
@@ -127,7 +127,7 @@ lbValue lb_const_ptr_cast(lbModule *m, lbValue value, Type *t) {
 	return res;
 	return res;
 }
 }
 
 
-LLVMValueRef llvm_const_named_struct(lbModule *m, Type *t, LLVMValueRef *values, isize value_count_) {
+gb_internal LLVMValueRef llvm_const_named_struct(lbModule *m, Type *t, LLVMValueRef *values, isize value_count_) {
 	LLVMTypeRef struct_type = lb_type(m, t);
 	LLVMTypeRef struct_type = lb_type(m, t);
 	GB_ASSERT(LLVMGetTypeKind(struct_type) == LLVMStructTypeKind);
 	GB_ASSERT(LLVMGetTypeKind(struct_type) == LLVMStructTypeKind);
 	
 	
@@ -157,7 +157,7 @@ LLVMValueRef llvm_const_named_struct(lbModule *m, Type *t, LLVMValueRef *values,
 	return llvm_const_named_struct_internal(struct_type, values_with_padding, values_with_padding_count);
 	return llvm_const_named_struct_internal(struct_type, values_with_padding, values_with_padding_count);
 }
 }
 
 
-LLVMValueRef llvm_const_named_struct_internal(LLVMTypeRef t, LLVMValueRef *values, isize value_count_) {
+gb_internal LLVMValueRef llvm_const_named_struct_internal(LLVMTypeRef t, LLVMValueRef *values, isize value_count_) {
 	unsigned value_count = cast(unsigned)value_count_;
 	unsigned value_count = cast(unsigned)value_count_;
 	unsigned elem_count = LLVMCountStructElementTypes(t);
 	unsigned elem_count = LLVMCountStructElementTypes(t);
 	GB_ASSERT_MSG(value_count == elem_count, "%s %u %u", LLVMPrintTypeToString(t), value_count, elem_count);
 	GB_ASSERT_MSG(value_count == elem_count, "%s %u %u", LLVMPrintTypeToString(t), value_count, elem_count);
@@ -168,7 +168,7 @@ LLVMValueRef llvm_const_named_struct_internal(LLVMTypeRef t, LLVMValueRef *value
 	return LLVMConstNamedStruct(t, values, value_count);
 	return LLVMConstNamedStruct(t, values, value_count);
 }
 }
 
 
-LLVMValueRef llvm_const_array(LLVMTypeRef elem_type, LLVMValueRef *values, isize value_count_) {
+gb_internal LLVMValueRef llvm_const_array(LLVMTypeRef elem_type, LLVMValueRef *values, isize value_count_) {
 	unsigned value_count = cast(unsigned)value_count_;
 	unsigned value_count = cast(unsigned)value_count_;
 	for (unsigned i = 0; i < value_count; i++) {
 	for (unsigned i = 0; i < value_count; i++) {
 		values[i] = llvm_const_cast(values[i], elem_type);
 		values[i] = llvm_const_cast(values[i], elem_type);
@@ -176,7 +176,7 @@ LLVMValueRef llvm_const_array(LLVMTypeRef elem_type, LLVMValueRef *values, isize
 	return LLVMConstArray(elem_type, values, value_count);
 	return LLVMConstArray(elem_type, values, value_count);
 }
 }
 
 
-LLVMValueRef llvm_const_slice(lbModule *m, lbValue data, lbValue len) {
+gb_internal LLVMValueRef llvm_const_slice(lbModule *m, lbValue data, lbValue len) {
 	GB_ASSERT(is_type_pointer(data.type) || is_type_multi_pointer(data.type));
 	GB_ASSERT(is_type_pointer(data.type) || is_type_multi_pointer(data.type));
 	GB_ASSERT(are_types_identical(len.type, t_int));
 	GB_ASSERT(are_types_identical(len.type, t_int));
 	LLVMValueRef vals[2] = {
 	LLVMValueRef vals[2] = {
@@ -187,38 +187,38 @@ LLVMValueRef llvm_const_slice(lbModule *m, lbValue data, lbValue len) {
 }
 }
 
 
 
 
-lbValue lb_const_nil(lbModule *m, Type *type) {
+gb_internal lbValue lb_const_nil(lbModule *m, Type *type) {
 	LLVMValueRef v = LLVMConstNull(lb_type(m, type));
 	LLVMValueRef v = LLVMConstNull(lb_type(m, type));
 	return lbValue{v, type};
 	return lbValue{v, type};
 }
 }
 
 
-lbValue lb_const_undef(lbModule *m, Type *type) {
+gb_internal lbValue lb_const_undef(lbModule *m, Type *type) {
 	LLVMValueRef v = LLVMGetUndef(lb_type(m, type));
 	LLVMValueRef v = LLVMGetUndef(lb_type(m, type));
 	return lbValue{v, type};
 	return lbValue{v, type};
 }
 }
 
 
 
 
 
 
-lbValue lb_const_int(lbModule *m, Type *type, u64 value) {
+gb_internal lbValue lb_const_int(lbModule *m, Type *type, u64 value) {
 	lbValue res = {};
 	lbValue res = {};
 	res.value = LLVMConstInt(lb_type(m, type), cast(unsigned long long)value, !is_type_unsigned(type));
 	res.value = LLVMConstInt(lb_type(m, type), cast(unsigned long long)value, !is_type_unsigned(type));
 	res.type = type;
 	res.type = type;
 	return res;
 	return res;
 }
 }
 
 
-lbValue lb_const_string(lbModule *m, String const &value) {
+gb_internal lbValue lb_const_string(lbModule *m, String const &value) {
 	return lb_const_value(m, t_string, exact_value_string(value));
 	return lb_const_value(m, t_string, exact_value_string(value));
 }
 }
 
 
 
 
-lbValue lb_const_bool(lbModule *m, Type *type, bool value) {
+gb_internal lbValue lb_const_bool(lbModule *m, Type *type, bool value) {
 	lbValue res = {};
 	lbValue res = {};
 	res.value = LLVMConstInt(lb_type(m, type), value, false);
 	res.value = LLVMConstInt(lb_type(m, type), value, false);
 	res.type = type;
 	res.type = type;
 	return res;
 	return res;
 }
 }
 
 
-LLVMValueRef lb_const_f16(lbModule *m, f32 f, Type *type=t_f16) {
+gb_internal LLVMValueRef lb_const_f16(lbModule *m, f32 f, Type *type=t_f16) {
 	GB_ASSERT(type_size_of(type) == 2);
 	GB_ASSERT(type_size_of(type) == 2);
 
 
 	u16 u = f32_to_f16(f);
 	u16 u = f32_to_f16(f);
@@ -229,7 +229,7 @@ LLVMValueRef lb_const_f16(lbModule *m, f32 f, Type *type=t_f16) {
 	return LLVMConstBitCast(i, lb_type(m, type));
 	return LLVMConstBitCast(i, lb_type(m, type));
 }
 }
 
 
-LLVMValueRef lb_const_f32(lbModule *m, f32 f, Type *type=t_f32) {
+gb_internal LLVMValueRef lb_const_f32(lbModule *m, f32 f, Type *type=t_f32) {
 	GB_ASSERT(type_size_of(type) == 4);
 	GB_ASSERT(type_size_of(type) == 4);
 	u32 u = bit_cast<u32>(f);
 	u32 u = bit_cast<u32>(f);
 	if (is_type_different_to_arch_endianness(type)) {
 	if (is_type_different_to_arch_endianness(type)) {
@@ -241,7 +241,7 @@ LLVMValueRef lb_const_f32(lbModule *m, f32 f, Type *type=t_f32) {
 
 
 
 
 
 
-bool lb_is_expr_untyped_const(Ast *expr) {
+gb_internal bool lb_is_expr_untyped_const(Ast *expr) {
 	auto const &tv = type_and_value_of_expr(expr);
 	auto const &tv = type_and_value_of_expr(expr);
 	if (is_type_untyped(tv.type)) {
 	if (is_type_untyped(tv.type)) {
 		return tv.value.kind != ExactValue_Invalid;
 		return tv.value.kind != ExactValue_Invalid;
@@ -250,13 +250,13 @@ bool lb_is_expr_untyped_const(Ast *expr) {
 }
 }
 
 
 
 
-lbValue lb_expr_untyped_const_to_typed(lbModule *m, Ast *expr, Type *t) {
+gb_internal lbValue lb_expr_untyped_const_to_typed(lbModule *m, Ast *expr, Type *t) {
 	GB_ASSERT(is_type_typed(t));
 	GB_ASSERT(is_type_typed(t));
 	auto const &tv = type_and_value_of_expr(expr);
 	auto const &tv = type_and_value_of_expr(expr);
 	return lb_const_value(m, t, tv.value);
 	return lb_const_value(m, t, tv.value);
 }
 }
 
 
-lbValue lb_emit_source_code_location_const(lbProcedure *p, String const &procedure, TokenPos const &pos) {
+gb_internal lbValue lb_emit_source_code_location_const(lbProcedure *p, String const &procedure, TokenPos const &pos) {
 	lbModule *m = p->module;
 	lbModule *m = p->module;
 
 
 	LLVMValueRef fields[4] = {};
 	LLVMValueRef fields[4] = {};
@@ -271,7 +271,7 @@ lbValue lb_emit_source_code_location_const(lbProcedure *p, String const &procedu
 	return res;
 	return res;
 }
 }
 
 
-lbValue lb_emit_source_code_location_const(lbProcedure *p, Ast *node) {
+gb_internal lbValue lb_emit_source_code_location_const(lbProcedure *p, Ast *node) {
 	String proc_name = {};
 	String proc_name = {};
 	if (p->entity) {
 	if (p->entity) {
 		proc_name = p->entity->token.string;
 		proc_name = p->entity->token.string;
@@ -284,7 +284,7 @@ lbValue lb_emit_source_code_location_const(lbProcedure *p, Ast *node) {
 }
 }
 
 
 
 
-lbValue lb_emit_source_code_location_as_global_ptr(lbProcedure *p, String const &procedure, TokenPos const &pos) {
+gb_internal lbValue lb_emit_source_code_location_as_global_ptr(lbProcedure *p, String const &procedure, TokenPos const &pos) {
 	lbValue loc = lb_emit_source_code_location_const(p, procedure, pos);
 	lbValue loc = lb_emit_source_code_location_const(p, procedure, pos);
 	lbAddr addr = lb_add_global_generated(p->module, loc.type, loc, nullptr);
 	lbAddr addr = lb_add_global_generated(p->module, loc.type, loc, nullptr);
 	lb_make_global_private_const(addr);
 	lb_make_global_private_const(addr);
@@ -292,24 +292,24 @@ lbValue lb_emit_source_code_location_as_global_ptr(lbProcedure *p, String const
 }
 }
 
 
 
 
-lbValue lb_emit_source_code_location_as_global_ptr(lbProcedure *p, Ast *node) {
+gb_internal lbValue lb_emit_source_code_location_as_global_ptr(lbProcedure *p, Ast *node) {
 	lbValue loc = lb_emit_source_code_location_const(p, node);
 	lbValue loc = lb_emit_source_code_location_const(p, node);
 	lbAddr addr = lb_add_global_generated(p->module, loc.type, loc, nullptr);
 	lbAddr addr = lb_add_global_generated(p->module, loc.type, loc, nullptr);
 	lb_make_global_private_const(addr);
 	lb_make_global_private_const(addr);
 	return addr.addr;
 	return addr.addr;
 }
 }
 
 
-lbValue lb_emit_source_code_location_as_global(lbProcedure *p, String const &procedure, TokenPos const &pos) {
+gb_internal lbValue lb_emit_source_code_location_as_global(lbProcedure *p, String const &procedure, TokenPos const &pos) {
 	return lb_emit_load(p, lb_emit_source_code_location_as_global_ptr(p, procedure, pos));
 	return lb_emit_load(p, lb_emit_source_code_location_as_global_ptr(p, procedure, pos));
 }
 }
 
 
-lbValue lb_emit_source_code_location_as_global(lbProcedure *p, Ast *node) {
+gb_internal lbValue lb_emit_source_code_location_as_global(lbProcedure *p, Ast *node) {
 	return lb_emit_load(p, lb_emit_source_code_location_as_global_ptr(p, node));
 	return lb_emit_load(p, lb_emit_source_code_location_as_global_ptr(p, node));
 }
 }
 
 
 
 
 
 
-LLVMValueRef lb_build_constant_array_values(lbModule *m, Type *type, Type *elem_type, isize count, LLVMValueRef *values, bool allow_local) {
+gb_internal LLVMValueRef lb_build_constant_array_values(lbModule *m, Type *type, Type *elem_type, isize count, LLVMValueRef *values, bool allow_local) {
 	bool is_local = allow_local && m->curr_procedure != nullptr;
 	bool is_local = allow_local && m->curr_procedure != nullptr;
 	bool is_const = true;
 	bool is_const = true;
 	if (is_local) {
 	if (is_local) {
@@ -341,7 +341,7 @@ LLVMValueRef lb_build_constant_array_values(lbModule *m, Type *type, Type *elem_
 	return llvm_const_array(lb_type(m, elem_type), values, cast(unsigned int)count);
 	return llvm_const_array(lb_type(m, elem_type), values, cast(unsigned int)count);
 }
 }
 
 
-LLVMValueRef lb_big_int_to_llvm(lbModule *m, Type *original_type, BigInt const *a) {
+gb_internal LLVMValueRef lb_big_int_to_llvm(lbModule *m, Type *original_type, BigInt const *a) {
 	if (big_int_is_zero(a)) {
 	if (big_int_is_zero(a)) {
 		return LLVMConstNull(lb_type(m, original_type));
 		return LLVMConstNull(lb_type(m, original_type));
 	}
 	}
@@ -387,7 +387,7 @@ LLVMValueRef lb_big_int_to_llvm(lbModule *m, Type *original_type, BigInt const *
 }
 }
 
 
 
 
-lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_local) {
+gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_local) {
 	LLVMContextRef ctx = m->ctx;
 	LLVMContextRef ctx = m->ctx;
 
 
 	type = default_type(type);
 	type = default_type(type);

+ 21 - 27
src/llvm_backend_debug.cpp

@@ -1,4 +1,4 @@
-LLVMMetadataRef lb_get_llvm_metadata(lbModule *m, void *key) {
+gb_internal LLVMMetadataRef lb_get_llvm_metadata(lbModule *m, void *key) {
 	if (key == nullptr) {
 	if (key == nullptr) {
 		return nullptr;
 		return nullptr;
 	}
 	}
@@ -8,20 +8,14 @@ LLVMMetadataRef lb_get_llvm_metadata(lbModule *m, void *key) {
 	}
 	}
 	return nullptr;
 	return nullptr;
 }
 }
-void lb_set_llvm_metadata(lbModule *m, void *key, LLVMMetadataRef value) {
+gb_internal void lb_set_llvm_metadata(lbModule *m, void *key, LLVMMetadataRef value) {
 	if (key != nullptr) {
 	if (key != nullptr) {
 		map_set(&m->debug_values, key, value);
 		map_set(&m->debug_values, key, value);
 	}
 	}
 }
 }
 
 
-LLVMMetadataRef lb_get_llvm_file_metadata_from_node(lbModule *m, Ast *node) {
-	if (node == nullptr) {
-		return nullptr;
-	}
-	return lb_get_llvm_metadata(m, node->file());
-}
 
 
-LLVMMetadataRef lb_get_current_debug_scope(lbProcedure *p) {
+gb_internal LLVMMetadataRef lb_get_current_debug_scope(lbProcedure *p) {
 	GB_ASSERT_MSG(p->debug_info != nullptr, "missing debug information for %.*s", LIT(p->name));
 	GB_ASSERT_MSG(p->debug_info != nullptr, "missing debug information for %.*s", LIT(p->name));
 
 
 	for (isize i = p->scope_stack.count-1; i >= 0; i--) {
 	for (isize i = p->scope_stack.count-1; i >= 0; i--) {
@@ -34,21 +28,21 @@ LLVMMetadataRef lb_get_current_debug_scope(lbProcedure *p) {
 	return p->debug_info;
 	return p->debug_info;
 }
 }
 
 
-LLVMMetadataRef lb_debug_location_from_token_pos(lbProcedure *p, TokenPos pos) {
+gb_internal LLVMMetadataRef lb_debug_location_from_token_pos(lbProcedure *p, TokenPos pos) {
 	LLVMMetadataRef scope = lb_get_current_debug_scope(p);
 	LLVMMetadataRef scope = lb_get_current_debug_scope(p);
 	GB_ASSERT_MSG(scope != nullptr, "%.*s", LIT(p->name));
 	GB_ASSERT_MSG(scope != nullptr, "%.*s", LIT(p->name));
 	return LLVMDIBuilderCreateDebugLocation(p->module->ctx, cast(unsigned)pos.line, cast(unsigned)pos.column, scope, nullptr);
 	return LLVMDIBuilderCreateDebugLocation(p->module->ctx, cast(unsigned)pos.line, cast(unsigned)pos.column, scope, nullptr);
 }
 }
-LLVMMetadataRef lb_debug_location_from_ast(lbProcedure *p, Ast *node) {
+gb_internal LLVMMetadataRef lb_debug_location_from_ast(lbProcedure *p, Ast *node) {
 	GB_ASSERT(node != nullptr);
 	GB_ASSERT(node != nullptr);
 	return lb_debug_location_from_token_pos(p, ast_token(node).pos);
 	return lb_debug_location_from_token_pos(p, ast_token(node).pos);
 }
 }
-LLVMMetadataRef lb_debug_end_location_from_ast(lbProcedure *p, Ast *node) {
+gb_internal LLVMMetadataRef lb_debug_end_location_from_ast(lbProcedure *p, Ast *node) {
 	GB_ASSERT(node != nullptr);
 	GB_ASSERT(node != nullptr);
 	return lb_debug_location_from_token_pos(p, ast_end_token(node).pos);
 	return lb_debug_location_from_token_pos(p, ast_end_token(node).pos);
 }
 }
 
 
-LLVMMetadataRef lb_debug_type_internal_proc(lbModule *m, Type *type) {
+gb_internal LLVMMetadataRef lb_debug_type_internal_proc(lbModule *m, Type *type) {
 	i64 size = type_size_of(type); // Check size
 	i64 size = type_size_of(type); // Check size
 	gb_unused(size);
 	gb_unused(size);
 
 
@@ -93,7 +87,7 @@ LLVMMetadataRef lb_debug_type_internal_proc(lbModule *m, Type *type) {
 	return LLVMDIBuilderCreateSubroutineType(m->debug_builder, file, parameters, parameter_count, flags);
 	return LLVMDIBuilderCreateSubroutineType(m->debug_builder, file, parameters, parameter_count, flags);
 }
 }
 
 
-LLVMMetadataRef lb_debug_struct_field(lbModule *m, String const &name, Type *type, u64 offset_in_bits) {
+gb_internal LLVMMetadataRef lb_debug_struct_field(lbModule *m, String const &name, Type *type, u64 offset_in_bits) {
 	unsigned field_line = 1;
 	unsigned field_line = 1;
 	LLVMDIFlags field_flags = LLVMDIFlagZero;
 	LLVMDIFlags field_flags = LLVMDIFlagZero;
 
 
@@ -107,7 +101,7 @@ LLVMMetadataRef lb_debug_struct_field(lbModule *m, String const &name, Type *typ
 		field_flags, lb_debug_type(m, type)
 		field_flags, lb_debug_type(m, type)
 	);
 	);
 }
 }
-LLVMMetadataRef lb_debug_basic_struct(lbModule *m, String const &name, u64 size_in_bits, u32 align_in_bits, LLVMMetadataRef *elements, unsigned element_count) {
+gb_internal LLVMMetadataRef lb_debug_basic_struct(lbModule *m, String const &name, u64 size_in_bits, u32 align_in_bits, LLVMMetadataRef *elements, unsigned element_count) {
 	AstPackage *pkg = m->info->runtime_package;
 	AstPackage *pkg = m->info->runtime_package;
 	GB_ASSERT(pkg->files.count != 0);
 	GB_ASSERT(pkg->files.count != 0);
 	LLVMMetadataRef file = lb_get_llvm_metadata(m, pkg->files[0]);
 	LLVMMetadataRef file = lb_get_llvm_metadata(m, pkg->files[0]);
@@ -117,7 +111,7 @@ LLVMMetadataRef lb_debug_basic_struct(lbModule *m, String const &name, u64 size_
 }
 }
 
 
 
 
-LLVMMetadataRef lb_debug_type_basic_type(lbModule *m, String const &name, u64 size_in_bits, LLVMDWARFTypeEncoding encoding, LLVMDIFlags flags = LLVMDIFlagZero) {
+gb_internal LLVMMetadataRef lb_debug_type_basic_type(lbModule *m, String const &name, u64 size_in_bits, LLVMDWARFTypeEncoding encoding, LLVMDIFlags flags = LLVMDIFlagZero) {
 	LLVMMetadataRef basic_type = LLVMDIBuilderCreateBasicType(m->debug_builder, cast(char const *)name.text, name.len, size_in_bits, encoding, flags);
 	LLVMMetadataRef basic_type = LLVMDIBuilderCreateBasicType(m->debug_builder, cast(char const *)name.text, name.len, size_in_bits, encoding, flags);
 #if 1
 #if 1
 	LLVMMetadataRef final_decl = LLVMDIBuilderCreateTypedef(m->debug_builder, basic_type, cast(char const *)name.text, name.len, nullptr, 0, nullptr, cast(u32)size_in_bits);
 	LLVMMetadataRef final_decl = LLVMDIBuilderCreateTypedef(m->debug_builder, basic_type, cast(char const *)name.text, name.len, nullptr, 0, nullptr, cast(u32)size_in_bits);
@@ -127,7 +121,7 @@ LLVMMetadataRef lb_debug_type_basic_type(lbModule *m, String const &name, u64 si
 #endif
 #endif
 }
 }
 
 
-LLVMMetadataRef lb_debug_type_internal(lbModule *m, Type *type) {
+gb_internal LLVMMetadataRef lb_debug_type_internal(lbModule *m, Type *type) {
 	i64 size = type_size_of(type); // Check size
 	i64 size = type_size_of(type); // Check size
 	gb_unused(size);
 	gb_unused(size);
 
 
@@ -474,7 +468,7 @@ LLVMMetadataRef lb_debug_type_internal(lbModule *m, Type *type) {
 	return nullptr;
 	return nullptr;
 }
 }
 
 
-LLVMMetadataRef lb_get_base_scope_metadata(lbModule *m, Scope *scope) {
+gb_internal LLVMMetadataRef lb_get_base_scope_metadata(lbModule *m, Scope *scope) {
 	LLVMMetadataRef found = nullptr;
 	LLVMMetadataRef found = nullptr;
 	for (;;) {
 	for (;;) {
 		if (scope == nullptr) {
 		if (scope == nullptr) {
@@ -496,7 +490,7 @@ LLVMMetadataRef lb_get_base_scope_metadata(lbModule *m, Scope *scope) {
 	}
 	}
 }
 }
 
 
-LLVMMetadataRef lb_debug_type(lbModule *m, Type *type) {
+gb_internal LLVMMetadataRef lb_debug_type(lbModule *m, Type *type) {
 	GB_ASSERT(type != nullptr);
 	GB_ASSERT(type != nullptr);
 	LLVMMetadataRef found = lb_get_llvm_metadata(m, type);
 	LLVMMetadataRef found = lb_get_llvm_metadata(m, type);
 	if (found != nullptr) {
 	if (found != nullptr) {
@@ -615,7 +609,7 @@ LLVMMetadataRef lb_debug_type(lbModule *m, Type *type) {
 	return dt;
 	return dt;
 }
 }
 
 
-void lb_debug_complete_types(lbModule *m) {
+gb_internal void lb_debug_complete_types(lbModule *m) {
 	/* unsigned const word_size = cast(unsigned)build_context.word_size; */
 	/* unsigned const word_size = cast(unsigned)build_context.word_size; */
 	unsigned const word_bits = cast(unsigned)(8*build_context.word_size);
 	unsigned const word_bits = cast(unsigned)(8*build_context.word_size);
 
 
@@ -962,7 +956,7 @@ void lb_debug_complete_types(lbModule *m) {
 
 
 
 
 
 
-void lb_add_debug_local_variable(lbProcedure *p, LLVMValueRef ptr, Type *type, Token const &token) {
+gb_internal void lb_add_debug_local_variable(lbProcedure *p, LLVMValueRef ptr, Type *type, Token const &token) {
 	if (p->debug_info == nullptr) {
 	if (p->debug_info == nullptr) {
 		return;
 		return;
 	}
 	}
@@ -1024,7 +1018,7 @@ void lb_add_debug_local_variable(lbProcedure *p, LLVMValueRef ptr, Type *type, T
 	LLVMDIBuilderInsertDeclareAtEnd(m->debug_builder, storage, var_info, llvm_expr, llvm_debug_loc, block);
 	LLVMDIBuilderInsertDeclareAtEnd(m->debug_builder, storage, var_info, llvm_expr, llvm_debug_loc, block);
 }
 }
 
 
-void lb_add_debug_param_variable(lbProcedure *p, LLVMValueRef ptr, Type *type, Token const &token, unsigned arg_number, lbBlock *block, lbArgKind arg_kind) {
+gb_internal void lb_add_debug_param_variable(lbProcedure *p, LLVMValueRef ptr, Type *type, Token const &token, unsigned arg_number, lbBlock *block, lbArgKind arg_kind) {
 	if (p->debug_info == nullptr) {
 	if (p->debug_info == nullptr) {
 		return;
 		return;
 	}
 	}
@@ -1097,7 +1091,7 @@ void lb_add_debug_param_variable(lbProcedure *p, LLVMValueRef ptr, Type *type, T
 }
 }
 
 
 
 
-void lb_add_debug_context_variable(lbProcedure *p, lbAddr const &ctx) {
+gb_internal void lb_add_debug_context_variable(lbProcedure *p, lbAddr const &ctx) {
 	if (!p->debug_info || !p->body) {
 	if (!p->debug_info || !p->body) {
 		return;
 		return;
 	}
 	}
@@ -1125,7 +1119,7 @@ void lb_add_debug_context_variable(lbProcedure *p, lbAddr const &ctx) {
 }
 }
 
 
 
 
-String debug_info_mangle_constant_name(Entity *e, bool *did_allocate_) {
+gb_internal String debug_info_mangle_constant_name(Entity *e, bool *did_allocate_) {
 	String name = e->token.string;
 	String name = e->token.string;
 	if (e->pkg && e->pkg->name.len > 0) {
 	if (e->pkg && e->pkg->name.len > 0) {
 		// NOTE(bill): C++ NONSENSE FOR DEBUG SHITE!
 		// NOTE(bill): C++ NONSENSE FOR DEBUG SHITE!
@@ -1135,7 +1129,7 @@ String debug_info_mangle_constant_name(Entity *e, bool *did_allocate_) {
 	return name;
 	return name;
 }
 }
 
 
-void add_debug_info_global_variable_expr(lbModule *m, String const &name, LLVMMetadataRef dtype, LLVMMetadataRef expr) {
+gb_internal void add_debug_info_global_variable_expr(lbModule *m, String const &name, LLVMMetadataRef dtype, LLVMMetadataRef expr) {
 	LLVMMetadataRef scope = nullptr;
 	LLVMMetadataRef scope = nullptr;
 	LLVMMetadataRef file = nullptr;
 	LLVMMetadataRef file = nullptr;
 	unsigned line = 0;
 	unsigned line = 0;
@@ -1151,7 +1145,7 @@ void add_debug_info_global_variable_expr(lbModule *m, String const &name, LLVMMe
 		expr, decl, 8/*AlignInBits*/);
 		expr, decl, 8/*AlignInBits*/);
 }
 }
 
 
-void add_debug_info_for_global_constant_internal_i64(lbModule *m, Entity *e, LLVMMetadataRef dtype, i64 v) {
+gb_internal void add_debug_info_for_global_constant_internal_i64(lbModule *m, Entity *e, LLVMMetadataRef dtype, i64 v) {
 	LLVMMetadataRef expr = LLVMDIBuilderCreateConstantValueExpression(m->debug_builder, v);
 	LLVMMetadataRef expr = LLVMDIBuilderCreateConstantValueExpression(m->debug_builder, v);
 
 
 	bool did_allocate = false;
 	bool did_allocate = false;
@@ -1167,7 +1161,7 @@ void add_debug_info_for_global_constant_internal_i64(lbModule *m, Entity *e, LLV
 	}
 	}
 }
 }
 
 
-void add_debug_info_for_global_constant_from_entity(lbGenerator *gen, Entity *e) {
+gb_internal void add_debug_info_for_global_constant_from_entity(lbGenerator *gen, Entity *e) {
 	if (e == nullptr || e->kind != Entity_Constant) {
 	if (e == nullptr || e->kind != Entity_Constant) {
 		return;
 		return;
 	}
 	}

+ 40 - 40
src/llvm_backend_expr.cpp

@@ -1,6 +1,6 @@
-lbValue lb_emit_arith_matrix(lbProcedure *p, TokenKind op, lbValue lhs, lbValue rhs, Type *type, bool component_wise);
+gb_internal lbValue lb_emit_arith_matrix(lbProcedure *p, TokenKind op, lbValue lhs, lbValue rhs, Type *type, bool component_wise);
 
 
-lbValue lb_emit_logical_binary_expr(lbProcedure *p, TokenKind op, Ast *left, Ast *right, Type *type) {
+gb_internal lbValue lb_emit_logical_binary_expr(lbProcedure *p, TokenKind op, Ast *left, Ast *right, Type *type) {
 	lbModule *m = p->module;
 	lbModule *m = p->module;
 
 
 	lbBlock *rhs  = lb_create_block(p, "logical.cmp.rhs");
 	lbBlock *rhs  = lb_create_block(p, "logical.cmp.rhs");
@@ -113,7 +113,7 @@ lbValue lb_emit_logical_binary_expr(lbProcedure *p, TokenKind op, Ast *left, Ast
 }
 }
 
 
 
 
-lbValue lb_emit_unary_arith(lbProcedure *p, TokenKind op, lbValue x, Type *type) {
+gb_internal lbValue lb_emit_unary_arith(lbProcedure *p, TokenKind op, lbValue x, Type *type) {
 	switch (op) {
 	switch (op) {
 	case Token_Add:
 	case Token_Add:
 		return x;
 		return x;
@@ -283,7 +283,7 @@ lbValue lb_emit_unary_arith(lbProcedure *p, TokenKind op, lbValue x, Type *type)
 	return res;
 	return res;
 }
 }
 
 
-bool lb_try_direct_vector_arith(lbProcedure *p, TokenKind op, lbValue lhs, lbValue rhs, Type *type, lbValue *res_) {
+gb_internal bool lb_try_direct_vector_arith(lbProcedure *p, TokenKind op, lbValue lhs, lbValue rhs, Type *type, lbValue *res_) {
 	GB_ASSERT(is_type_array_like(type));
 	GB_ASSERT(is_type_array_like(type));
 	Type *elem_type = base_array_type(type);
 	Type *elem_type = base_array_type(type);
 
 
@@ -418,7 +418,7 @@ bool lb_try_direct_vector_arith(lbProcedure *p, TokenKind op, lbValue lhs, lbVal
 }
 }
 
 
 
 
-lbValue lb_emit_arith_array(lbProcedure *p, TokenKind op, lbValue lhs, lbValue rhs, Type *type) {
+gb_internal lbValue lb_emit_arith_array(lbProcedure *p, TokenKind op, lbValue lhs, lbValue rhs, Type *type) {
 	GB_ASSERT(is_type_array_like(lhs.type) || is_type_array_like(rhs.type));
 	GB_ASSERT(is_type_array_like(lhs.type) || is_type_array_like(rhs.type));
 
 
 	lhs = lb_emit_conv(p, lhs, type);
 	lhs = lb_emit_conv(p, lhs, type);
@@ -490,7 +490,7 @@ lbValue lb_emit_arith_array(lbProcedure *p, TokenKind op, lbValue lhs, lbValue r
 	}
 	}
 }
 }
 
 
-bool lb_is_matrix_simdable(Type *t) {
+gb_internal bool lb_is_matrix_simdable(Type *t) {
 	Type *mt = base_type(t);
 	Type *mt = base_type(t);
 	GB_ASSERT(mt->kind == Type_Matrix);
 	GB_ASSERT(mt->kind == Type_Matrix);
 	
 	
@@ -534,7 +534,7 @@ bool lb_is_matrix_simdable(Type *t) {
 }
 }
 
 
 
 
-LLVMValueRef lb_matrix_to_vector(lbProcedure *p, lbValue matrix) {
+gb_internal LLVMValueRef lb_matrix_to_vector(lbProcedure *p, lbValue matrix) {
 	Type *mt = base_type(matrix.type);
 	Type *mt = base_type(matrix.type);
 	GB_ASSERT(mt->kind == Type_Matrix);
 	GB_ASSERT(mt->kind == Type_Matrix);
 	LLVMTypeRef elem_type = lb_type(p->module, mt->Matrix.elem);
 	LLVMTypeRef elem_type = lb_type(p->module, mt->Matrix.elem);
@@ -554,7 +554,7 @@ LLVMValueRef lb_matrix_to_vector(lbProcedure *p, lbValue matrix) {
 #endif
 #endif
 }
 }
 
 
-LLVMValueRef lb_matrix_trimmed_vector_mask(lbProcedure *p, Type *mt) {
+gb_internal LLVMValueRef lb_matrix_trimmed_vector_mask(lbProcedure *p, Type *mt) {
 	mt = base_type(mt);
 	mt = base_type(mt);
 	GB_ASSERT(mt->kind == Type_Matrix);
 	GB_ASSERT(mt->kind == Type_Matrix);
 
 
@@ -574,7 +574,7 @@ LLVMValueRef lb_matrix_trimmed_vector_mask(lbProcedure *p, Type *mt) {
 	return mask;
 	return mask;
 }
 }
 
 
-LLVMValueRef lb_matrix_to_trimmed_vector(lbProcedure *p, lbValue m) {
+gb_internal LLVMValueRef lb_matrix_to_trimmed_vector(lbProcedure *p, lbValue m) {
 	LLVMValueRef vector = lb_matrix_to_vector(p, m);
 	LLVMValueRef vector = lb_matrix_to_vector(p, m);
 
 
 	Type *mt = base_type(m.type);
 	Type *mt = base_type(m.type);
@@ -592,7 +592,7 @@ LLVMValueRef lb_matrix_to_trimmed_vector(lbProcedure *p, lbValue m) {
 }
 }
 
 
 
 
-lbValue lb_emit_matrix_tranpose(lbProcedure *p, lbValue m, Type *type) {
+gb_internal lbValue lb_emit_matrix_tranpose(lbProcedure *p, lbValue m, Type *type) {
 	if (is_type_array(m.type)) {
 	if (is_type_array(m.type)) {
 		i32 rank = type_math_rank(m.type);
 		i32 rank = type_math_rank(m.type);
 		if (rank == 2) {
 		if (rank == 2) {
@@ -669,7 +669,7 @@ lbValue lb_emit_matrix_tranpose(lbProcedure *p, lbValue m, Type *type) {
 	return lb_addr_load(p, res);
 	return lb_addr_load(p, res);
 }
 }
 
 
-lbValue lb_matrix_cast_vector_to_type(lbProcedure *p, LLVMValueRef vector, Type *type) {
+gb_internal lbValue lb_matrix_cast_vector_to_type(lbProcedure *p, LLVMValueRef vector, Type *type) {
 	lbAddr res = lb_add_local_generated(p, type, true);
 	lbAddr res = lb_add_local_generated(p, type, true);
 	LLVMValueRef res_ptr = res.addr.value;
 	LLVMValueRef res_ptr = res.addr.value;
 	unsigned alignment = cast(unsigned)gb_max(type_align_of(type), lb_alignof(LLVMTypeOf(vector)));
 	unsigned alignment = cast(unsigned)gb_max(type_align_of(type), lb_alignof(LLVMTypeOf(vector)));
@@ -681,7 +681,7 @@ lbValue lb_matrix_cast_vector_to_type(lbProcedure *p, LLVMValueRef vector, Type
 	return lb_addr_load(p, res);
 	return lb_addr_load(p, res);
 }
 }
 
 
-lbValue lb_emit_matrix_flatten(lbProcedure *p, lbValue m, Type *type) {
+gb_internal lbValue lb_emit_matrix_flatten(lbProcedure *p, lbValue m, Type *type) {
 	if (is_type_array(m.type)) {
 	if (is_type_array(m.type)) {
 		// no-op
 		// no-op
 		m.type = type;
 		m.type = type;
@@ -710,7 +710,7 @@ lbValue lb_emit_matrix_flatten(lbProcedure *p, lbValue m, Type *type) {
 }
 }
 
 
 
 
-lbValue lb_emit_outer_product(lbProcedure *p, lbValue a, lbValue b, Type *type) {
+gb_internal lbValue lb_emit_outer_product(lbProcedure *p, lbValue a, lbValue b, Type *type) {
 	Type *mt = base_type(type);
 	Type *mt = base_type(type);
 	Type *at = base_type(a.type);
 	Type *at = base_type(a.type);
 	Type *bt = base_type(b.type);
 	Type *bt = base_type(b.type);
@@ -741,7 +741,7 @@ lbValue lb_emit_outer_product(lbProcedure *p, lbValue a, lbValue b, Type *type)
 
 
 }
 }
 
 
-lbValue lb_emit_matrix_mul(lbProcedure *p, lbValue lhs, lbValue rhs, Type *type) {
+gb_internal lbValue lb_emit_matrix_mul(lbProcedure *p, lbValue lhs, lbValue rhs, Type *type) {
 	// TODO(bill): Handle edge case for f16 types on x86(-64) platforms
 	// TODO(bill): Handle edge case for f16 types on x86(-64) platforms
 
 
 	Type *xt = base_type(lhs.type);
 	Type *xt = base_type(lhs.type);
@@ -828,7 +828,7 @@ lbValue lb_emit_matrix_mul(lbProcedure *p, lbValue lhs, lbValue rhs, Type *type)
 	}
 	}
 }
 }
 
 
-lbValue lb_emit_matrix_mul_vector(lbProcedure *p, lbValue lhs, lbValue rhs, Type *type) {
+gb_internal lbValue lb_emit_matrix_mul_vector(lbProcedure *p, lbValue lhs, lbValue rhs, Type *type) {
 	// TODO(bill): Handle edge case for f16 types on x86(-64) platforms
 	// TODO(bill): Handle edge case for f16 types on x86(-64) platforms
 
 
 	Type *mt = base_type(lhs.type);
 	Type *mt = base_type(lhs.type);
@@ -897,7 +897,7 @@ lbValue lb_emit_matrix_mul_vector(lbProcedure *p, lbValue lhs, lbValue rhs, Type
 	return lb_addr_load(p, res);
 	return lb_addr_load(p, res);
 }
 }
 
 
-lbValue lb_emit_vector_mul_matrix(lbProcedure *p, lbValue lhs, lbValue rhs, Type *type) {
+gb_internal lbValue lb_emit_vector_mul_matrix(lbProcedure *p, lbValue lhs, lbValue rhs, Type *type) {
 	// TODO(bill): Handle edge case for f16 types on x86(-64) platforms
 	// TODO(bill): Handle edge case for f16 types on x86(-64) platforms
 
 
 	Type *mt = base_type(rhs.type);
 	Type *mt = base_type(rhs.type);
@@ -984,7 +984,7 @@ lbValue lb_emit_vector_mul_matrix(lbProcedure *p, lbValue lhs, lbValue rhs, Type
 
 
 
 
 
 
-lbValue lb_emit_arith_matrix(lbProcedure *p, TokenKind op, lbValue lhs, lbValue rhs, Type *type, bool component_wise) {
+gb_internal lbValue lb_emit_arith_matrix(lbProcedure *p, TokenKind op, lbValue lhs, lbValue rhs, Type *type, bool component_wise) {
 	GB_ASSERT(is_type_matrix(lhs.type) || is_type_matrix(rhs.type));
 	GB_ASSERT(is_type_matrix(lhs.type) || is_type_matrix(rhs.type));
 
 
 	if (op == Token_Mul && !component_wise) {
 	if (op == Token_Mul && !component_wise) {
@@ -1056,7 +1056,7 @@ lbValue lb_emit_arith_matrix(lbProcedure *p, TokenKind op, lbValue lhs, lbValue
 
 
 
 
 
 
-lbValue lb_emit_arith(lbProcedure *p, TokenKind op, lbValue lhs, lbValue rhs, Type *type) {
+gb_internal lbValue lb_emit_arith(lbProcedure *p, TokenKind op, lbValue lhs, lbValue rhs, Type *type) {
 	if (is_type_array_like(lhs.type) || is_type_array_like(rhs.type)) {
 	if (is_type_array_like(lhs.type) || is_type_array_like(rhs.type)) {
 		return lb_emit_arith_array(p, op, lhs, rhs, type);
 		return lb_emit_arith_array(p, op, lhs, rhs, type);
 	} else if (is_type_matrix(lhs.type) || is_type_matrix(rhs.type)) {
 	} else if (is_type_matrix(lhs.type) || is_type_matrix(rhs.type)) {
@@ -1325,7 +1325,7 @@ handle_op:
 	return {};
 	return {};
 }
 }
 
 
-lbValue lb_build_binary_expr(lbProcedure *p, Ast *expr) {
+gb_internal lbValue lb_build_binary_expr(lbProcedure *p, Ast *expr) {
 	ast_node(be, BinaryExpr, expr);
 	ast_node(be, BinaryExpr, expr);
 
 
 	TypeAndValue tv = type_and_value_of_expr(expr);
 	TypeAndValue tv = type_and_value_of_expr(expr);
@@ -1472,7 +1472,7 @@ lbValue lb_build_binary_expr(lbProcedure *p, Ast *expr) {
 	return {};
 	return {};
 }
 }
 
 
-lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) {
+gb_internal lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) {
 	lbModule *m = p->module;
 	lbModule *m = p->module;
 	t = reduce_tuple_to_single_type(t);
 	t = reduce_tuple_to_single_type(t);
 
 
@@ -2202,7 +2202,7 @@ lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) {
 	return {};
 	return {};
 }
 }
 
 
-lbValue lb_compare_records(lbProcedure *p, TokenKind op_kind, lbValue left, lbValue right, Type *type) {
+gb_internal lbValue lb_compare_records(lbProcedure *p, TokenKind op_kind, lbValue left, lbValue right, Type *type) {
 	GB_ASSERT((is_type_struct(type) || is_type_union(type)) && is_type_comparable(type));
 	GB_ASSERT((is_type_struct(type) || is_type_union(type)) && is_type_comparable(type));
 	lbValue left_ptr  = lb_address_from_load_or_generate_local(p, left);
 	lbValue left_ptr  = lb_address_from_load_or_generate_local(p, left);
 	lbValue right_ptr = lb_address_from_load_or_generate_local(p, right);
 	lbValue right_ptr = lb_address_from_load_or_generate_local(p, right);
@@ -2230,7 +2230,7 @@ lbValue lb_compare_records(lbProcedure *p, TokenKind op_kind, lbValue left, lbVa
 
 
 
 
 
 
-lbValue lb_emit_comp(lbProcedure *p, TokenKind op_kind, lbValue left, lbValue right) {
+gb_internal lbValue lb_emit_comp(lbProcedure *p, TokenKind op_kind, lbValue left, lbValue right) {
 	Type *a = core_type(left.type);
 	Type *a = core_type(left.type);
 	Type *b = core_type(right.type);
 	Type *b = core_type(right.type);
 
 
@@ -2642,7 +2642,7 @@ lbValue lb_emit_comp(lbProcedure *p, TokenKind op_kind, lbValue left, lbValue ri
 
 
 
 
 
 
-lbValue lb_emit_comp_against_nil(lbProcedure *p, TokenKind op_kind, lbValue x) {
+gb_internal lbValue lb_emit_comp_against_nil(lbProcedure *p, TokenKind op_kind, lbValue x) {
 	lbValue res = {};
 	lbValue res = {};
 	res.type = t_llvm_bool;
 	res.type = t_llvm_bool;
 	Type *t = x.type;
 	Type *t = x.type;
@@ -2803,7 +2803,7 @@ lbValue lb_emit_comp_against_nil(lbProcedure *p, TokenKind op_kind, lbValue x) {
 	return {};
 	return {};
 }
 }
 
 
-lbValue lb_make_soa_pointer(lbProcedure *p, Type *type, lbValue const &addr, lbValue const &index) {
+gb_internal lbValue lb_make_soa_pointer(lbProcedure *p, Type *type, lbValue const &addr, lbValue const &index) {
 	lbAddr v = lb_add_local_generated(p, type, false);
 	lbAddr v = lb_add_local_generated(p, type, false);
 	lbValue ptr = lb_emit_struct_ep(p, v.addr, 0);
 	lbValue ptr = lb_emit_struct_ep(p, v.addr, 0);
 	lbValue idx = lb_emit_struct_ep(p, v.addr, 1);
 	lbValue idx = lb_emit_struct_ep(p, v.addr, 1);
@@ -2813,7 +2813,7 @@ lbValue lb_make_soa_pointer(lbProcedure *p, Type *type, lbValue const &addr, lbV
 	return lb_addr_load(p, v);
 	return lb_addr_load(p, v);
 }
 }
 
 
-lbValue lb_build_unary_and(lbProcedure *p, Ast *expr) {
+gb_internal lbValue lb_build_unary_and(lbProcedure *p, Ast *expr) {
 	ast_node(ue, UnaryExpr, expr);
 	ast_node(ue, UnaryExpr, expr);
 	auto tv = type_and_value_of_expr(expr);
 	auto tv = type_and_value_of_expr(expr);
 
 
@@ -3023,8 +3023,8 @@ lbValue lb_build_unary_and(lbProcedure *p, Ast *expr) {
 	return lb_build_addr_ptr(p, ue->expr);
 	return lb_build_addr_ptr(p, ue->expr);
 }
 }
 
 
-lbValue lb_build_expr_internal(lbProcedure *p, Ast *expr);
-lbValue lb_build_expr(lbProcedure *p, Ast *expr) {
+gb_internal lbValue lb_build_expr_internal(lbProcedure *p, Ast *expr);
+gb_internal lbValue lb_build_expr(lbProcedure *p, Ast *expr) {
 	u16 prev_state_flags = p->state_flags;
 	u16 prev_state_flags = p->state_flags;
 	defer (p->state_flags = prev_state_flags);
 	defer (p->state_flags = prev_state_flags);
 
 
@@ -3080,7 +3080,7 @@ lbValue lb_build_expr(lbProcedure *p, Ast *expr) {
 	return res;
 	return res;
 }
 }
 
 
-lbValue lb_build_expr_internal(lbProcedure *p, Ast *expr) {
+gb_internal lbValue lb_build_expr_internal(lbProcedure *p, Ast *expr) {
 	lbModule *m = p->module;
 	lbModule *m = p->module;
 
 
 	expr = unparen_expr(expr);
 	expr = unparen_expr(expr);
@@ -3355,10 +3355,10 @@ lbValue lb_build_expr_internal(lbProcedure *p, Ast *expr) {
 	return {};
 	return {};
 }
 }
 
 
-lbAddr lb_get_soa_variable_addr(lbProcedure *p, Entity *e) {
+gb_internal lbAddr lb_get_soa_variable_addr(lbProcedure *p, Entity *e) {
 	return map_must_get(&p->module->soa_values, e);
 	return map_must_get(&p->module->soa_values, e);
 }
 }
-lbValue lb_get_using_variable(lbProcedure *p, Entity *e) {
+gb_internal lbValue lb_get_using_variable(lbProcedure *p, Entity *e) {
 	GB_ASSERT(e->kind == Entity_Variable && e->flags & EntityFlag_Using);
 	GB_ASSERT(e->kind == Entity_Variable && e->flags & EntityFlag_Using);
 	String name = e->token.string;
 	String name = e->token.string;
 	Entity *parent = e->using_parent;
 	Entity *parent = e->using_parent;
@@ -3393,7 +3393,7 @@ lbValue lb_get_using_variable(lbProcedure *p, Entity *e) {
 
 
 
 
 
 
-lbAddr lb_build_addr_from_entity(lbProcedure *p, Entity *e, Ast *expr) {
+gb_internal lbAddr lb_build_addr_from_entity(lbProcedure *p, Entity *e, Ast *expr) {
 	GB_ASSERT(e != nullptr);
 	GB_ASSERT(e != nullptr);
 	if (e->kind == Entity_Constant) {
 	if (e->kind == Entity_Constant) {
 		Type *t = default_type(type_of_expr(expr));
 		Type *t = default_type(type_of_expr(expr));
@@ -3427,7 +3427,7 @@ lbAddr lb_build_addr_from_entity(lbProcedure *p, Entity *e, Ast *expr) {
 	return lb_addr(v);
 	return lb_addr(v);
 }
 }
 
 
-lbAddr lb_build_array_swizzle_addr(lbProcedure *p, AstCallExpr *ce, TypeAndValue const &tv) {
+gb_internal lbAddr lb_build_array_swizzle_addr(lbProcedure *p, AstCallExpr *ce, TypeAndValue const &tv) {
 	isize index_count = ce->args.count-1;
 	isize index_count = ce->args.count-1;
 	lbAddr addr = lb_build_addr(p, ce->args[0]);
 	lbAddr addr = lb_build_addr(p, ce->args[0]);
 	if (index_count == 0) {
 	if (index_count == 0) {
@@ -3463,8 +3463,8 @@ lbAddr lb_build_array_swizzle_addr(lbProcedure *p, AstCallExpr *ce, TypeAndValue
 }
 }
 
 
 
 
-lbAddr lb_build_addr_internal(lbProcedure *p, Ast *expr);
-lbAddr lb_build_addr(lbProcedure *p, Ast *expr) {
+gb_internal lbAddr lb_build_addr_internal(lbProcedure *p, Ast *expr);
+gb_internal lbAddr lb_build_addr(lbProcedure *p, Ast *expr) {
 	expr = unparen_expr(expr);
 	expr = unparen_expr(expr);
 
 
 	// IMPORTANT NOTE(bill):
 	// IMPORTANT NOTE(bill):
@@ -3489,7 +3489,7 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) {
 	return addr;
 	return addr;
 }
 }
 
 
-void lb_build_addr_compound_lit_populate(lbProcedure *p, Slice<Ast *> const &elems, Array<lbCompoundLitElemTempData> *temp_data, Type *compound_type) {
+gb_internal void lb_build_addr_compound_lit_populate(lbProcedure *p, Slice<Ast *> const &elems, Array<lbCompoundLitElemTempData> *temp_data, Type *compound_type) {
 	Type *bt = base_type(compound_type);
 	Type *bt = base_type(compound_type);
 	Type *et = nullptr;
 	Type *et = nullptr;
 	switch (bt->kind) {
 	switch (bt->kind) {
@@ -3595,7 +3595,7 @@ void lb_build_addr_compound_lit_populate(lbProcedure *p, Slice<Ast *> const &ele
 		}
 		}
 	}
 	}
 }
 }
-void lb_build_addr_compound_lit_assign_array(lbProcedure *p, Array<lbCompoundLitElemTempData> const &temp_data) {
+gb_internal void lb_build_addr_compound_lit_assign_array(lbProcedure *p, Array<lbCompoundLitElemTempData> const &temp_data) {
 	for_array(i, temp_data) {
 	for_array(i, temp_data) {
 		auto td = temp_data[i];
 		auto td = temp_data[i];
 		if (td.value.value != nullptr) {
 		if (td.value.value != nullptr) {
@@ -3614,7 +3614,7 @@ void lb_build_addr_compound_lit_assign_array(lbProcedure *p, Array<lbCompoundLit
 	}
 	}
 }
 }
 
 
-lbAddr lb_build_addr_index_expr(lbProcedure *p, Ast *expr) {
+gb_internal lbAddr lb_build_addr_index_expr(lbProcedure *p, Ast *expr) {
 	ast_node(ie, IndexExpr, expr);
 	ast_node(ie, IndexExpr, expr);
 
 
 	Type *t = base_type(type_of_expr(ie->expr));
 	Type *t = base_type(type_of_expr(ie->expr));
@@ -3833,7 +3833,7 @@ lbAddr lb_build_addr_index_expr(lbProcedure *p, Ast *expr) {
 }
 }
 
 
 
 
-lbAddr lb_build_addr_slice_expr(lbProcedure *p, Ast *expr) {
+gb_internal lbAddr lb_build_addr_slice_expr(lbProcedure *p, Ast *expr) {
 	ast_node(se, SliceExpr, expr);
 	ast_node(se, SliceExpr, expr);
 
 
 	lbValue low  = lb_const_int(p->module, t_int, 0);
 	lbValue low  = lb_const_int(p->module, t_int, 0);
@@ -4031,7 +4031,7 @@ lbAddr lb_build_addr_slice_expr(lbProcedure *p, Ast *expr) {
 }
 }
 
 
 
 
-lbAddr lb_build_addr_compound_lit(lbProcedure *p, Ast *expr) {
+gb_internal lbAddr lb_build_addr_compound_lit(lbProcedure *p, Ast *expr) {
 	ast_node(cl, CompoundLit, expr);
 	ast_node(cl, CompoundLit, expr);
 
 
 	Type *type = type_of_expr(expr);
 	Type *type = type_of_expr(expr);
@@ -4383,7 +4383,7 @@ lbAddr lb_build_addr_compound_lit(lbProcedure *p, Ast *expr) {
 }
 }
 
 
 
 
-lbAddr lb_build_addr_internal(lbProcedure *p, Ast *expr) {
+gb_internal lbAddr lb_build_addr_internal(lbProcedure *p, Ast *expr) {
 	switch (expr->kind) {
 	switch (expr->kind) {
 	case_ast_node(i, Implicit, expr);
 	case_ast_node(i, Implicit, expr);
 		lbAddr v = {};
 		lbAddr v = {};

+ 89 - 157
src/llvm_backend_general.cpp

@@ -1,4 +1,4 @@
-void lb_add_debug_local_variable(lbProcedure *p, LLVMValueRef ptr, Type *type, Token const &token);
+gb_internal void lb_add_debug_local_variable(lbProcedure *p, LLVMValueRef ptr, Type *type, Token const &token);
 
 
 gb_global Entity *lb_global_type_info_data_entity   = {};
 gb_global Entity *lb_global_type_info_data_entity   = {};
 gb_global lbAddr lb_global_type_info_member_types   = {};
 gb_global lbAddr lb_global_type_info_member_types   = {};
@@ -15,7 +15,7 @@ gb_global isize lb_global_type_info_member_usings_index  = 0;
 gb_global isize lb_global_type_info_member_tags_index    = 0;
 gb_global isize lb_global_type_info_member_tags_index    = 0;
 
 
 
 
-void lb_init_module(lbModule *m, Checker *c) {
+gb_internal void lb_init_module(lbModule *m, Checker *c) {
 	m->info = &c->info;
 	m->info = &c->info;
 
 
 	gbString module_name = gb_string_make(heap_allocator(), "odin_package");
 	gbString module_name = gb_string_make(heap_allocator(), "odin_package");
@@ -82,7 +82,7 @@ void lb_init_module(lbModule *m, Checker *c) {
 
 
 }
 }
 
 
-bool lb_init_generator(lbGenerator *gen, Checker *c) {
+gb_internal bool lb_init_generator(lbGenerator *gen, Checker *c) {
 	if (global_error_collector.count != 0) {
 	if (global_error_collector.count != 0) {
 		return false;
 		return false;
 	}
 	}
@@ -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);
 	}
 	}
@@ -164,7 +164,7 @@ bool lb_init_generator(lbGenerator *gen, Checker *c) {
 
 
 
 
 
 
-lbValue lb_global_type_info_data_ptr(lbModule *m) {
+gb_internal lbValue lb_global_type_info_data_ptr(lbModule *m) {
 	lbValue v = lb_find_value_from_entity(m, lb_global_type_info_data_entity);
 	lbValue v = lb_find_value_from_entity(m, lb_global_type_info_data_entity);
 	return v;
 	return v;
 }
 }
@@ -187,7 +187,7 @@ struct lbCompoundLitElemTempData {
 };
 };
 
 
 
 
-lbLoopData lb_loop_start(lbProcedure *p, isize count, Type *index_type=t_i32) {
+gb_internal lbLoopData lb_loop_start(lbProcedure *p, isize count, Type *index_type=t_i32) {
 	lbLoopData data = {};
 	lbLoopData data = {};
 
 
 	lbValue max = lb_const_int(p->module, t_int, count);
 	lbValue max = lb_const_int(p->module, t_int, count);
@@ -210,7 +210,7 @@ lbLoopData lb_loop_start(lbProcedure *p, isize count, Type *index_type=t_i32) {
 	return data;
 	return data;
 }
 }
 
 
-void lb_loop_end(lbProcedure *p, lbLoopData const &data) {
+gb_internal void lb_loop_end(lbProcedure *p, lbLoopData const &data) {
 	if (data.idx_addr.addr.value != nullptr) {
 	if (data.idx_addr.addr.value != nullptr) {
 		lb_emit_increment(p, data.idx_addr.addr);
 		lb_emit_increment(p, data.idx_addr.addr);
 		lb_emit_jump(p, data.loop);
 		lb_emit_jump(p, data.loop);
@@ -219,19 +219,19 @@ void lb_loop_end(lbProcedure *p, lbLoopData const &data) {
 }
 }
 
 
 
 
-void lb_make_global_private_const(LLVMValueRef global_data) {
+gb_internal void lb_make_global_private_const(LLVMValueRef global_data) {
 	LLVMSetLinkage(global_data, LLVMPrivateLinkage);
 	LLVMSetLinkage(global_data, LLVMPrivateLinkage);
 	LLVMSetUnnamedAddress(global_data, LLVMGlobalUnnamedAddr);
 	LLVMSetUnnamedAddress(global_data, LLVMGlobalUnnamedAddr);
 	LLVMSetGlobalConstant(global_data, true);
 	LLVMSetGlobalConstant(global_data, true);
 }
 }
-void lb_make_global_private_const(lbAddr const &addr) {
+gb_internal void lb_make_global_private_const(lbAddr const &addr) {
 	lb_make_global_private_const(addr.addr.value);
 	lb_make_global_private_const(addr.addr.value);
 }
 }
 
 
 
 
 
 
 // This emits a GEP at 0, index
 // This emits a GEP at 0, index
-lbValue lb_emit_epi(lbProcedure *p, lbValue const &value, isize index) {
+gb_internal lbValue lb_emit_epi(lbProcedure *p, lbValue const &value, isize index) {
 	GB_ASSERT(is_type_pointer(value.type));
 	GB_ASSERT(is_type_pointer(value.type));
 	Type *type = type_deref(value.type);
 	Type *type = type_deref(value.type);
 
 
@@ -251,7 +251,7 @@ lbValue lb_emit_epi(lbProcedure *p, lbValue const &value, isize index) {
 	return res;
 	return res;
 }
 }
 // This emits a GEP at 0, index
 // This emits a GEP at 0, index
-lbValue lb_emit_epi(lbModule *m, lbValue const &value, isize index) {
+gb_internal lbValue lb_emit_epi(lbModule *m, lbValue const &value, isize index) {
 	GB_ASSERT(is_type_pointer(value.type));
 	GB_ASSERT(is_type_pointer(value.type));
 	GB_ASSERT(LLVMIsConstant(value.value));
 	GB_ASSERT(LLVMIsConstant(value.value));
 	Type *type = type_deref(value.type);
 	Type *type = type_deref(value.type);
@@ -269,17 +269,11 @@ lbValue lb_emit_epi(lbModule *m, lbValue const &value, isize index) {
 
 
 
 
 
 
-LLVMValueRef llvm_zero(lbModule *m) {
+gb_internal LLVMValueRef llvm_zero(lbModule *m) {
 	return LLVMConstInt(lb_type(m, t_int), 0, false);
 	return LLVMConstInt(lb_type(m, t_int), 0, false);
 }
 }
-LLVMValueRef llvm_zero32(lbModule *m) {
-	return LLVMConstInt(lb_type(m, t_i32), 0, false);
-}
-LLVMValueRef llvm_one(lbModule *m) {
-	return LLVMConstInt(lb_type(m, t_i32), 1, false);
-}
 
 
-LLVMValueRef llvm_alloca(lbProcedure *p, LLVMTypeRef llvm_type, isize alignment, char const *name) {
+gb_internal LLVMValueRef llvm_alloca(lbProcedure *p, LLVMTypeRef llvm_type, isize alignment, char const *name) {
 	LLVMPositionBuilderAtEnd(p->builder, p->decl_block->block);
 	LLVMPositionBuilderAtEnd(p->builder, p->decl_block->block);
 
 
 	LLVMValueRef val = LLVMBuildAlloca(p->builder, llvm_type, name);
 	LLVMValueRef val = LLVMBuildAlloca(p->builder, llvm_type, name);
@@ -290,20 +284,20 @@ LLVMValueRef llvm_alloca(lbProcedure *p, LLVMTypeRef llvm_type, isize alignment,
 	return val;
 	return val;
 }
 }
 
 
-lbValue lb_zero(lbModule *m, Type *t) {
+gb_internal lbValue lb_zero(lbModule *m, Type *t) {
 	lbValue v = {};
 	lbValue v = {};
 	v.value = LLVMConstInt(lb_type(m, t), 0, false);
 	v.value = LLVMConstInt(lb_type(m, t), 0, false);
 	v.type = t;
 	v.type = t;
 	return v;
 	return v;
 }
 }
 
 
-LLVMValueRef llvm_cstring(lbModule *m, String const &str) {
+gb_internal LLVMValueRef llvm_cstring(lbModule *m, String const &str) {
 	lbValue v = lb_find_or_add_entity_string(m, str);
 	lbValue v = lb_find_or_add_entity_string(m, str);
 	unsigned indices[1] = {0};
 	unsigned indices[1] = {0};
 	return LLVMConstExtractValue(v.value, indices, gb_count_of(indices));
 	return LLVMConstExtractValue(v.value, indices, gb_count_of(indices));
 }
 }
 
 
-bool lb_is_instr_terminating(LLVMValueRef instr) {
+gb_internal bool lb_is_instr_terminating(LLVMValueRef instr) {
 	if (instr != nullptr) {
 	if (instr != nullptr) {
 		LLVMOpcode op = LLVMGetInstructionOpcode(instr);
 		LLVMOpcode op = LLVMGetInstructionOpcode(instr);
 		switch (op) {
 		switch (op) {
@@ -322,7 +316,7 @@ bool lb_is_instr_terminating(LLVMValueRef instr) {
 
 
 
 
 
 
-lbModule *lb_pkg_module(lbGenerator *gen, AstPackage *pkg) {
+gb_internal lbModule *lb_pkg_module(lbGenerator *gen, AstPackage *pkg) {
 	auto *found = map_get(&gen->modules, pkg);
 	auto *found = map_get(&gen->modules, pkg);
 	if (found) {
 	if (found) {
 		return *found;
 		return *found;
@@ -331,7 +325,7 @@ lbModule *lb_pkg_module(lbGenerator *gen, AstPackage *pkg) {
 }
 }
 
 
 
 
-lbAddr lb_addr(lbValue addr) {
+gb_internal lbAddr lb_addr(lbValue addr) {
 	lbAddr v = {lbAddr_Default, addr};
 	lbAddr v = {lbAddr_Default, addr};
 	if (addr.type != nullptr && is_type_relative_pointer(type_deref(addr.type))) {
 	if (addr.type != nullptr && is_type_relative_pointer(type_deref(addr.type))) {
 		GB_ASSERT(is_type_pointer(addr.type));
 		GB_ASSERT(is_type_pointer(addr.type));
@@ -344,7 +338,7 @@ lbAddr lb_addr(lbValue addr) {
 }
 }
 
 
 
 
-lbAddr lb_addr_map(lbValue addr, lbValue map_key, Type *map_type, Type *map_result) {
+gb_internal lbAddr lb_addr_map(lbValue addr, lbValue map_key, Type *map_type, Type *map_result) {
 	GB_ASSERT(is_type_pointer(addr.type));
 	GB_ASSERT(is_type_pointer(addr.type));
 	Type *mt = type_deref(addr.type);
 	Type *mt = type_deref(addr.type);
 	GB_ASSERT(is_type_map(mt));
 	GB_ASSERT(is_type_map(mt));
@@ -357,14 +351,14 @@ lbAddr lb_addr_map(lbValue addr, lbValue map_key, Type *map_type, Type *map_resu
 }
 }
 
 
 
 
-lbAddr lb_addr_soa_variable(lbValue addr, lbValue index, Ast *index_expr) {
+gb_internal lbAddr lb_addr_soa_variable(lbValue addr, lbValue index, Ast *index_expr) {
 	lbAddr v = {lbAddr_SoaVariable, addr};
 	lbAddr v = {lbAddr_SoaVariable, addr};
 	v.soa.index = index;
 	v.soa.index = index;
 	v.soa.index_expr = index_expr;
 	v.soa.index_expr = index_expr;
 	return v;
 	return v;
 }
 }
 
 
-lbAddr lb_addr_swizzle(lbValue addr, Type *array_type, u8 swizzle_count, u8 swizzle_indices[4]) {
+gb_internal lbAddr lb_addr_swizzle(lbValue addr, Type *array_type, u8 swizzle_count, u8 swizzle_indices[4]) {
 	GB_ASSERT(is_type_array(array_type));
 	GB_ASSERT(is_type_array(array_type));
 	GB_ASSERT(1 < swizzle_count && swizzle_count <= 4);
 	GB_ASSERT(1 < swizzle_count && swizzle_count <= 4);
 	lbAddr v = {lbAddr_Swizzle, addr};
 	lbAddr v = {lbAddr_Swizzle, addr};
@@ -374,7 +368,7 @@ lbAddr lb_addr_swizzle(lbValue addr, Type *array_type, u8 swizzle_count, u8 swiz
 	return v;
 	return v;
 }
 }
 
 
-lbAddr lb_addr_swizzle_large(lbValue addr, Type *array_type, Slice<i32> const &swizzle_indices) {
+gb_internal lbAddr lb_addr_swizzle_large(lbValue addr, Type *array_type, Slice<i32> const &swizzle_indices) {
 	GB_ASSERT_MSG(is_type_array(array_type), "%s", type_to_string(array_type));
 	GB_ASSERT_MSG(is_type_array(array_type), "%s", type_to_string(array_type));
 	lbAddr v = {lbAddr_SwizzleLarge, addr};
 	lbAddr v = {lbAddr_SwizzleLarge, addr};
 	v.swizzle_large.type = array_type;
 	v.swizzle_large.type = array_type;
@@ -382,7 +376,7 @@ lbAddr lb_addr_swizzle_large(lbValue addr, Type *array_type, Slice<i32> const &s
 	return v;
 	return v;
 }
 }
 
 
-Type *lb_addr_type(lbAddr const &addr) {
+gb_internal Type *lb_addr_type(lbAddr const &addr) {
 	if (addr.addr.value == nullptr) {
 	if (addr.addr.value == nullptr) {
 		return nullptr;
 		return nullptr;
 	}
 	}
@@ -411,7 +405,7 @@ Type *lb_addr_type(lbAddr const &addr) {
 	return type_deref(addr.addr.type);
 	return type_deref(addr.addr.type);
 }
 }
 
 
-lbValue lb_addr_get_ptr(lbProcedure *p, lbAddr const &addr) {
+gb_internal lbValue lb_addr_get_ptr(lbProcedure *p, lbAddr const &addr) {
 	if (addr.addr.value == nullptr) {
 	if (addr.addr.value == nullptr) {
 		GB_PANIC("Illegal addr -> nullptr");
 		GB_PANIC("Illegal addr -> nullptr");
 		return {};
 		return {};
@@ -462,12 +456,12 @@ lbValue lb_addr_get_ptr(lbProcedure *p, lbAddr const &addr) {
 }
 }
 
 
 
 
-lbValue lb_build_addr_ptr(lbProcedure *p, Ast *expr) {
+gb_internal lbValue lb_build_addr_ptr(lbProcedure *p, Ast *expr) {
 	lbAddr addr = lb_build_addr(p, expr);
 	lbAddr addr = lb_build_addr(p, expr);
 	return lb_addr_get_ptr(p, addr);
 	return lb_addr_get_ptr(p, addr);
 }
 }
 
 
-void lb_emit_bounds_check(lbProcedure *p, Token token, lbValue index, lbValue len) {
+gb_internal void lb_emit_bounds_check(lbProcedure *p, Token token, lbValue index, lbValue len) {
 	if (build_context.no_bounds_check) {
 	if (build_context.no_bounds_check) {
 		return;
 		return;
 	}
 	}
@@ -492,7 +486,7 @@ void lb_emit_bounds_check(lbProcedure *p, Token token, lbValue index, lbValue le
 	lb_emit_runtime_call(p, "bounds_check_error", args);
 	lb_emit_runtime_call(p, "bounds_check_error", args);
 }
 }
 
 
-void lb_emit_matrix_bounds_check(lbProcedure *p, Token token, lbValue row_index, lbValue column_index, lbValue row_count, lbValue column_count) {
+gb_internal void lb_emit_matrix_bounds_check(lbProcedure *p, Token token, lbValue row_index, lbValue column_index, lbValue row_count, lbValue column_count) {
 	if (build_context.no_bounds_check) {
 	if (build_context.no_bounds_check) {
 		return;
 		return;
 	}
 	}
@@ -522,7 +516,7 @@ void lb_emit_matrix_bounds_check(lbProcedure *p, Token token, lbValue row_index,
 }
 }
 
 
 
 
-void lb_emit_multi_pointer_slice_bounds_check(lbProcedure *p, Token token, lbValue low, lbValue high) {
+gb_internal void lb_emit_multi_pointer_slice_bounds_check(lbProcedure *p, Token token, lbValue low, lbValue high) {
 	if (build_context.no_bounds_check) {
 	if (build_context.no_bounds_check) {
 		return;
 		return;
 	}
 	}
@@ -547,7 +541,7 @@ void lb_emit_multi_pointer_slice_bounds_check(lbProcedure *p, Token token, lbVal
 	lb_emit_runtime_call(p, "multi_pointer_slice_expr_error", args);
 	lb_emit_runtime_call(p, "multi_pointer_slice_expr_error", args);
 }
 }
 
 
-void lb_emit_slice_bounds_check(lbProcedure *p, Token token, lbValue low, lbValue high, lbValue len, bool lower_value_used) {
+gb_internal void lb_emit_slice_bounds_check(lbProcedure *p, Token token, lbValue low, lbValue high, lbValue len, bool lower_value_used) {
 	if (build_context.no_bounds_check) {
 	if (build_context.no_bounds_check) {
 		return;
 		return;
 	}
 	}
@@ -585,14 +579,14 @@ void lb_emit_slice_bounds_check(lbProcedure *p, Token token, lbValue low, lbValu
 	}
 	}
 }
 }
 
 
-unsigned lb_try_get_alignment(LLVMValueRef addr_ptr, unsigned default_alignment) {
+gb_internal unsigned lb_try_get_alignment(LLVMValueRef addr_ptr, unsigned default_alignment) {
 	if (LLVMIsAGlobalValue(addr_ptr) || LLVMIsAAllocaInst(addr_ptr) || LLVMIsALoadInst(addr_ptr)) {
 	if (LLVMIsAGlobalValue(addr_ptr) || LLVMIsAAllocaInst(addr_ptr) || LLVMIsALoadInst(addr_ptr)) {
 		return LLVMGetAlignment(addr_ptr);
 		return LLVMGetAlignment(addr_ptr);
 	}
 	}
 	return default_alignment;
 	return default_alignment;
 }
 }
 
 
-bool lb_try_update_alignment(LLVMValueRef addr_ptr, unsigned alignment) {
+gb_internal bool lb_try_update_alignment(LLVMValueRef addr_ptr, unsigned alignment) {
 	if (LLVMIsAGlobalValue(addr_ptr) || LLVMIsAAllocaInst(addr_ptr) || LLVMIsALoadInst(addr_ptr)) {
 	if (LLVMIsAGlobalValue(addr_ptr) || LLVMIsAAllocaInst(addr_ptr) || LLVMIsALoadInst(addr_ptr)) {
 		if (LLVMGetAlignment(addr_ptr) < alignment) {
 		if (LLVMGetAlignment(addr_ptr) < alignment) {
 			if (LLVMIsAAllocaInst(addr_ptr) || LLVMIsAGlobalValue(addr_ptr)) {
 			if (LLVMIsAAllocaInst(addr_ptr) || LLVMIsAGlobalValue(addr_ptr)) {
@@ -604,15 +598,15 @@ bool lb_try_update_alignment(LLVMValueRef addr_ptr, unsigned alignment) {
 	return false;
 	return false;
 }
 }
 
 
-bool lb_try_update_alignment(lbValue ptr, unsigned alignment) {
+gb_internal bool lb_try_update_alignment(lbValue ptr, unsigned alignment) {
 	return lb_try_update_alignment(ptr.value, alignment);
 	return lb_try_update_alignment(ptr.value, alignment);
 }
 }
 
 
-bool lb_can_try_to_inline_array_arith(Type *t) {
+gb_internal bool lb_can_try_to_inline_array_arith(Type *t) {
 	return type_size_of(t) <= build_context.max_simd_align;
 	return type_size_of(t) <= build_context.max_simd_align;
 }
 }
 
 
-bool lb_try_vector_cast(lbModule *m, lbValue ptr, LLVMTypeRef *vector_type_) {
+gb_internal bool lb_try_vector_cast(lbModule *m, lbValue ptr, LLVMTypeRef *vector_type_) {
 	Type *array_type = base_type(type_deref(ptr.type));
 	Type *array_type = base_type(type_deref(ptr.type));
 	GB_ASSERT(is_type_array_like(array_type));
 	GB_ASSERT(is_type_array_like(array_type));
 	i64 count = get_array_type_count(array_type);
 	i64 count = get_array_type_count(array_type);
@@ -647,7 +641,7 @@ bool lb_try_vector_cast(lbModule *m, lbValue ptr, LLVMTypeRef *vector_type_) {
 	return false;
 	return false;
 }
 }
 
 
-void lb_addr_store(lbProcedure *p, lbAddr addr, lbValue value) {
+gb_internal void lb_addr_store(lbProcedure *p, lbAddr addr, lbValue value) {
 	if (addr.addr.value == nullptr) {
 	if (addr.addr.value == nullptr) {
 		return;
 		return;
 	}
 	}
@@ -874,15 +868,7 @@ void lb_addr_store(lbProcedure *p, lbAddr addr, lbValue value) {
 	lb_emit_store(p, addr.addr, value);
 	lb_emit_store(p, addr.addr, value);
 }
 }
 
 
-void lb_const_store(lbValue ptr, lbValue value) {
-	GB_ASSERT(lb_is_const(ptr));
-	GB_ASSERT(lb_is_const(value));
-	GB_ASSERT(is_type_pointer(ptr.type));
-	LLVMSetInitializer(ptr.value, value.value);
-}
-
-
-bool lb_is_type_proc_recursive(Type *t) {
+gb_internal bool lb_is_type_proc_recursive(Type *t) {
 	for (;;) {
 	for (;;) {
 		if (t == nullptr) {
 		if (t == nullptr) {
 			return false;
 			return false;
@@ -902,7 +888,7 @@ bool lb_is_type_proc_recursive(Type *t) {
 	}
 	}
 }
 }
 
 
-void lb_emit_store(lbProcedure *p, lbValue ptr, lbValue value) {
+gb_internal void lb_emit_store(lbProcedure *p, lbValue ptr, lbValue value) {
 	GB_ASSERT(value.value != nullptr);
 	GB_ASSERT(value.value != nullptr);
 	Type *a = type_deref(ptr.type);
 	Type *a = type_deref(ptr.type);
 
 
@@ -978,11 +964,11 @@ void lb_emit_store(lbProcedure *p, lbValue ptr, lbValue value) {
 	}
 	}
 }
 }
 
 
-LLVMTypeRef llvm_addr_type(lbModule *module, lbValue addr_val) {
+gb_internal LLVMTypeRef llvm_addr_type(lbModule *module, lbValue addr_val) {
 	return lb_type(module, type_deref(addr_val.type));
 	return lb_type(module, type_deref(addr_val.type));
 }
 }
 
 
-lbValue lb_emit_load(lbProcedure *p, lbValue value) {
+gb_internal lbValue lb_emit_load(lbProcedure *p, lbValue value) {
 	GB_ASSERT(value.value != nullptr);
 	GB_ASSERT(value.value != nullptr);
 	if (is_type_multi_pointer(value.type)) {
 	if (is_type_multi_pointer(value.type)) {
 		Type *vt = base_type(value.type);
 		Type *vt = base_type(value.type);
@@ -1003,7 +989,7 @@ lbValue lb_emit_load(lbProcedure *p, lbValue value) {
 	return lbValue{v, t};
 	return lbValue{v, t};
 }
 }
 
 
-lbValue lb_addr_load(lbProcedure *p, lbAddr const &addr) {
+gb_internal lbValue lb_addr_load(lbProcedure *p, lbAddr const &addr) {
 	GB_ASSERT(addr.addr.value != nullptr);
 	GB_ASSERT(addr.addr.value != nullptr);
 
 
 
 
@@ -1243,11 +1229,11 @@ lbValue lb_addr_load(lbProcedure *p, lbAddr const &addr) {
 	return lb_emit_load(p, addr.addr);
 	return lb_emit_load(p, addr.addr);
 }
 }
 
 
-lbValue lb_const_union_tag(lbModule *m, Type *u, Type *v) {
+gb_internal lbValue lb_const_union_tag(lbModule *m, Type *u, Type *v) {
 	return lb_const_value(m, union_tag_type(u), exact_value_i64(union_variant_index(u, v)));
 	return lb_const_value(m, union_tag_type(u), exact_value_i64(union_variant_index(u, v)));
 }
 }
 
 
-lbValue lb_emit_union_tag_ptr(lbProcedure *p, lbValue u) {
+gb_internal lbValue lb_emit_union_tag_ptr(lbProcedure *p, lbValue u) {
 	Type *t = u.type;
 	Type *t = u.type;
 	GB_ASSERT_MSG(is_type_pointer(t) &&
 	GB_ASSERT_MSG(is_type_pointer(t) &&
 	              is_type_union(type_deref(t)), "%s", type_to_string(t));
 	              is_type_union(type_deref(t)), "%s", type_to_string(t));
@@ -1269,14 +1255,14 @@ lbValue lb_emit_union_tag_ptr(lbProcedure *p, lbValue u) {
 	return tag_ptr;
 	return tag_ptr;
 }
 }
 
 
-lbValue lb_emit_union_tag_value(lbProcedure *p, lbValue u) {
+gb_internal lbValue lb_emit_union_tag_value(lbProcedure *p, lbValue u) {
 	lbValue ptr = lb_address_from_load_or_generate_local(p, u);
 	lbValue ptr = lb_address_from_load_or_generate_local(p, u);
 	lbValue tag_ptr = lb_emit_union_tag_ptr(p, ptr);
 	lbValue tag_ptr = lb_emit_union_tag_ptr(p, ptr);
 	return lb_emit_load(p, tag_ptr);
 	return lb_emit_load(p, tag_ptr);
 }
 }
 
 
 
 
-void lb_emit_store_union_variant_tag(lbProcedure *p, lbValue parent, Type *variant_type) {
+gb_internal void lb_emit_store_union_variant_tag(lbProcedure *p, lbValue parent, Type *variant_type) {
 	Type *t = type_deref(parent.type);
 	Type *t = type_deref(parent.type);
 
 
 	if (is_type_union_maybe_pointer(t) || type_size_of(t) == 0) {
 	if (is_type_union_maybe_pointer(t) || type_size_of(t) == 0) {
@@ -1287,7 +1273,7 @@ void lb_emit_store_union_variant_tag(lbProcedure *p, lbValue parent, Type *varia
 	}
 	}
 }
 }
 
 
-void lb_emit_store_union_variant(lbProcedure *p, lbValue parent, lbValue variant, Type *variant_type) {
+gb_internal void lb_emit_store_union_variant(lbProcedure *p, lbValue parent, lbValue variant, Type *variant_type) {
 	Type *pt = base_type(type_deref(parent.type));
 	Type *pt = base_type(type_deref(parent.type));
 	GB_ASSERT(pt->kind == Type_Union);
 	GB_ASSERT(pt->kind == Type_Union);
 	if (pt->Union.kind == UnionType_shared_nil) {
 	if (pt->Union.kind == UnionType_shared_nil) {
@@ -1320,29 +1306,14 @@ void lb_emit_store_union_variant(lbProcedure *p, lbValue parent, lbValue variant
 }
 }
 
 
 
 
-void lb_clone_struct_type(LLVMTypeRef dst, LLVMTypeRef src) {
+gb_internal void lb_clone_struct_type(LLVMTypeRef dst, LLVMTypeRef src) {
 	unsigned field_count = LLVMCountStructElementTypes(src);
 	unsigned field_count = LLVMCountStructElementTypes(src);
 	LLVMTypeRef *fields = gb_alloc_array(temporary_allocator(), LLVMTypeRef, field_count);
 	LLVMTypeRef *fields = gb_alloc_array(temporary_allocator(), LLVMTypeRef, field_count);
 	LLVMGetStructElementTypes(src, fields);
 	LLVMGetStructElementTypes(src, fields);
 	LLVMStructSetBody(dst, fields, field_count, LLVMIsPackedStruct(src));
 	LLVMStructSetBody(dst, fields, field_count, LLVMIsPackedStruct(src));
 }
 }
 
 
-LLVMTypeRef lb_alignment_prefix_type_hack(lbModule *m, i64 alignment) {
-	switch (alignment) {
-	case 1:
-		return LLVMArrayType(lb_type(m, t_u8), 0);
-	case 2:
-		return LLVMArrayType(lb_type(m, t_u16), 0);
-	case 4:
-		return LLVMArrayType(lb_type(m, t_u32), 0);
-	case 8:
-		return LLVMArrayType(lb_type(m, t_u64), 0);
-	default: case 16:
-		return LLVMArrayType(LLVMVectorType(lb_type(m, t_u32), 4), 0);
-	}
-}
-
-String lb_mangle_name(lbModule *m, Entity *e) {
+gb_internal String lb_mangle_name(lbModule *m, Entity *e) {
 	String name = e->token.string;
 	String name = e->token.string;
 
 
 	AstPackage *pkg = e->pkg;
 	AstPackage *pkg = e->pkg;
@@ -1384,7 +1355,7 @@ String lb_mangle_name(lbModule *m, Entity *e) {
 	return mangled_name;
 	return mangled_name;
 }
 }
 
 
-String lb_set_nested_type_name_ir_mangled_name(Entity *e, lbProcedure *p) {
+gb_internal String lb_set_nested_type_name_ir_mangled_name(Entity *e, lbProcedure *p) {
 	// NOTE(bill, 2020-03-08): A polymorphic procedure may take a nested type declaration
 	// NOTE(bill, 2020-03-08): A polymorphic procedure may take a nested type declaration
 	// and as a result, the declaration does not have time to determine what it should be
 	// and as a result, the declaration does not have time to determine what it should be
 
 
@@ -1440,7 +1411,7 @@ String lb_set_nested_type_name_ir_mangled_name(Entity *e, lbProcedure *p) {
 	}
 	}
 }
 }
 
 
-String lb_get_entity_name(lbModule *m, Entity *e, String default_name) {
+gb_internal String lb_get_entity_name(lbModule *m, Entity *e, String default_name) {
 	if (e != nullptr && e->kind == Entity_TypeName && e->TypeName.ir_mangled_name.len != 0) {
 	if (e != nullptr && e->kind == Entity_TypeName && e->TypeName.ir_mangled_name.len != 0) {
 		return e->TypeName.ir_mangled_name;
 		return e->TypeName.ir_mangled_name;
 	}
 	}
@@ -1488,7 +1459,7 @@ String lb_get_entity_name(lbModule *m, Entity *e, String default_name) {
 }
 }
 
 
 
 
-LLVMTypeRef lb_type_internal_for_procedures_raw(lbModule *m, Type *type) {
+gb_internal LLVMTypeRef lb_type_internal_for_procedures_raw(lbModule *m, Type *type) {
 	Type *original_type = type;
 	Type *original_type = type;
 	type = base_type(original_type);
 	type = base_type(original_type);
 	GB_ASSERT(type->kind == Type_Proc);
 	GB_ASSERT(type->kind == Type_Proc);
@@ -1607,7 +1578,7 @@ LLVMTypeRef lb_type_internal_for_procedures_raw(lbModule *m, Type *type) {
 	return new_abi_fn_type;
 	return new_abi_fn_type;
 
 
 }
 }
-LLVMTypeRef lb_type_internal(lbModule *m, Type *type) {
+gb_internal LLVMTypeRef lb_type_internal(lbModule *m, Type *type) {
 	LLVMContextRef ctx = m->ctx;
 	LLVMContextRef ctx = m->ctx;
 	i64 size = type_size_of(type); // Check size
 	i64 size = type_size_of(type); // Check size
 	gb_unused(size);
 	gb_unused(size);
@@ -2145,7 +2116,7 @@ LLVMTypeRef lb_type_internal(lbModule *m, Type *type) {
 	return LLVMInt32TypeInContext(ctx);
 	return LLVMInt32TypeInContext(ctx);
 }
 }
 
 
-LLVMTypeRef lb_type(lbModule *m, Type *type) {
+gb_internal LLVMTypeRef lb_type(lbModule *m, Type *type) {
 	type = default_type(type);
 	type = default_type(type);
 
 
 	LLVMTypeRef *found = map_get(&m->types, type);
 	LLVMTypeRef *found = map_get(&m->types, type);
@@ -2164,7 +2135,7 @@ LLVMTypeRef lb_type(lbModule *m, Type *type) {
 	return llvm_type;
 	return llvm_type;
 }
 }
 
 
-lbFunctionType *lb_get_function_type(lbModule *m, Type *pt) {
+gb_internal lbFunctionType *lb_get_function_type(lbModule *m, Type *pt) {
 	lbFunctionType **ft_found = nullptr;
 	lbFunctionType **ft_found = nullptr;
 	ft_found = map_get(&m->function_type_map, pt);
 	ft_found = map_get(&m->function_type_map, pt);
 	if (!ft_found) {
 	if (!ft_found) {
@@ -2177,7 +2148,7 @@ lbFunctionType *lb_get_function_type(lbModule *m, Type *pt) {
 	return *ft_found;
 	return *ft_found;
 }
 }
 
 
-void lb_ensure_abi_function_type(lbModule *m, lbProcedure *p) {
+gb_internal void lb_ensure_abi_function_type(lbModule *m, lbProcedure *p) {
 	if (p->abi_function_type != nullptr) {
 	if (p->abi_function_type != nullptr) {
 		return;
 		return;
 	}
 	}
@@ -2192,20 +2163,17 @@ void lb_ensure_abi_function_type(lbModule *m, lbProcedure *p) {
 	GB_ASSERT(p->abi_function_type != nullptr);
 	GB_ASSERT(p->abi_function_type != nullptr);
 }
 }
 
 
-void lb_add_entity(lbModule *m, Entity *e, lbValue val) {
+gb_internal void lb_add_entity(lbModule *m, Entity *e, lbValue val) {
 	if (e != nullptr) {
 	if (e != nullptr) {
 		map_set(&m->values, e, val);
 		map_set(&m->values, e, val);
 	}
 	}
 }
 }
-void lb_add_member(lbModule *m, String const &name, lbValue val) {
+gb_internal void lb_add_member(lbModule *m, String const &name, lbValue val) {
 	if (name.len > 0) {
 	if (name.len > 0) {
 		string_map_set(&m->members, name, val);
 		string_map_set(&m->members, name, val);
 	}
 	}
 }
 }
-void lb_add_member(lbModule *m, StringHashKey const &key, lbValue val) {
-	string_map_set(&m->members, key, val);
-}
-void lb_add_procedure_value(lbModule *m, lbProcedure *p) {
+gb_internal void lb_add_procedure_value(lbModule *m, lbProcedure *p) {
 	if (p->entity != nullptr) {
 	if (p->entity != nullptr) {
 		map_set(&m->procedure_values, p->value, p->entity);
 		map_set(&m->procedure_values, p->value, p->entity);
 	}
 	}
@@ -2214,7 +2182,7 @@ void lb_add_procedure_value(lbModule *m, lbProcedure *p) {
 
 
 
 
 
 
-LLVMAttributeRef lb_create_enum_attribute_with_type(LLVMContextRef ctx, char const *name, LLVMTypeRef type) {
+gb_internal LLVMAttributeRef lb_create_enum_attribute_with_type(LLVMContextRef ctx, char const *name, LLVMTypeRef type) {
 	unsigned kind = 0;
 	unsigned kind = 0;
 	String s = make_string_c(name);
 	String s = make_string_c(name);
 
 
@@ -2243,7 +2211,7 @@ LLVMAttributeRef lb_create_enum_attribute_with_type(LLVMContextRef ctx, char con
 	#endif	
 	#endif	
 }
 }
 
 
-LLVMAttributeRef lb_create_enum_attribute(LLVMContextRef ctx, char const *name, u64 value) {
+gb_internal LLVMAttributeRef lb_create_enum_attribute(LLVMContextRef ctx, char const *name, u64 value) {
 	String s = make_string_c(name);
 	String s = make_string_c(name);
 
 
 	// NOTE(2021-02-25, bill); All this attributes require a type associated with them
 	// NOTE(2021-02-25, bill); All this attributes require a type associated with them
@@ -2264,23 +2232,23 @@ LLVMAttributeRef lb_create_enum_attribute(LLVMContextRef ctx, char const *name,
 	return LLVMCreateEnumAttribute(ctx, kind, value);
 	return LLVMCreateEnumAttribute(ctx, kind, value);
 }
 }
 
 
-void lb_add_proc_attribute_at_index(lbProcedure *p, isize index, char const *name, u64 value) {
+gb_internal void lb_add_proc_attribute_at_index(lbProcedure *p, isize index, char const *name, u64 value) {
 	LLVMAttributeRef attr = lb_create_enum_attribute(p->module->ctx, name, value);
 	LLVMAttributeRef attr = lb_create_enum_attribute(p->module->ctx, name, value);
 	GB_ASSERT(attr != nullptr);
 	GB_ASSERT(attr != nullptr);
 	LLVMAddAttributeAtIndex(p->value, cast(unsigned)index, attr);
 	LLVMAddAttributeAtIndex(p->value, cast(unsigned)index, attr);
 }
 }
 
 
-void lb_add_proc_attribute_at_index(lbProcedure *p, isize index, char const *name) {
+gb_internal void lb_add_proc_attribute_at_index(lbProcedure *p, isize index, char const *name) {
 	lb_add_proc_attribute_at_index(p, index, name, 0);
 	lb_add_proc_attribute_at_index(p, index, name, 0);
 }
 }
 
 
-void lb_add_attribute_to_proc(lbModule *m, LLVMValueRef proc_value, char const *name, u64 value=0) {
+gb_internal void lb_add_attribute_to_proc(lbModule *m, LLVMValueRef proc_value, char const *name, u64 value=0) {
 	LLVMAddAttributeAtIndex(proc_value, LLVMAttributeIndex_FunctionIndex, lb_create_enum_attribute(m->ctx, name, value));
 	LLVMAddAttributeAtIndex(proc_value, LLVMAttributeIndex_FunctionIndex, lb_create_enum_attribute(m->ctx, name, value));
 }
 }
 
 
 
 
 
 
-void lb_add_edge(lbBlock *from, lbBlock *to) {
+gb_internal void lb_add_edge(lbBlock *from, lbBlock *to) {
 	LLVMValueRef instr = LLVMGetLastInstruction(from->block);
 	LLVMValueRef instr = LLVMGetLastInstruction(from->block);
 	if (instr == nullptr || !LLVMIsATerminatorInst(instr)) {
 	if (instr == nullptr || !LLVMIsATerminatorInst(instr)) {
 		array_add(&from->succs, to);
 		array_add(&from->succs, to);
@@ -2289,7 +2257,7 @@ void lb_add_edge(lbBlock *from, lbBlock *to) {
 }
 }
 
 
 
 
-lbBlock *lb_create_block(lbProcedure *p, char const *name, bool append) {
+gb_internal lbBlock *lb_create_block(lbProcedure *p, char const *name, bool append) {
 	lbBlock *b = gb_alloc_item(permanent_allocator(), lbBlock);
 	lbBlock *b = gb_alloc_item(permanent_allocator(), lbBlock);
 	b->block = LLVMCreateBasicBlockInContext(p->module->ctx, name);
 	b->block = LLVMCreateBasicBlockInContext(p->module->ctx, name);
 	b->appended = false;
 	b->appended = false;
@@ -2309,7 +2277,7 @@ lbBlock *lb_create_block(lbProcedure *p, char const *name, bool append) {
 	return b;
 	return b;
 }
 }
 
 
-void lb_emit_jump(lbProcedure *p, lbBlock *target_block) {
+gb_internal void lb_emit_jump(lbProcedure *p, lbBlock *target_block) {
 	if (p->curr_block == nullptr) {
 	if (p->curr_block == nullptr) {
 		return;
 		return;
 	}
 	}
@@ -2323,7 +2291,7 @@ void lb_emit_jump(lbProcedure *p, lbBlock *target_block) {
 	p->curr_block = nullptr;
 	p->curr_block = nullptr;
 }
 }
 
 
-void lb_emit_if(lbProcedure *p, lbValue cond, lbBlock *true_block, lbBlock *false_block) {
+gb_internal void lb_emit_if(lbProcedure *p, lbValue cond, lbBlock *true_block, lbBlock *false_block) {
 	lbBlock *b = p->curr_block;
 	lbBlock *b = p->curr_block;
 	if (b == nullptr) {
 	if (b == nullptr) {
 		return;
 		return;
@@ -2342,20 +2310,20 @@ void lb_emit_if(lbProcedure *p, lbValue cond, lbBlock *true_block, lbBlock *fals
 }
 }
 
 
 
 
-gb_inline LLVMTypeRef OdinLLVMGetInternalElementType(LLVMTypeRef type) {
+gb_internal gb_inline LLVMTypeRef OdinLLVMGetInternalElementType(LLVMTypeRef type) {
 	return LLVMGetElementType(type);
 	return LLVMGetElementType(type);
 }
 }
-LLVMTypeRef OdinLLVMGetArrayElementType(LLVMTypeRef type) {
+gb_internal LLVMTypeRef OdinLLVMGetArrayElementType(LLVMTypeRef type) {
 	GB_ASSERT(lb_is_type_kind(type, LLVMArrayTypeKind));
 	GB_ASSERT(lb_is_type_kind(type, LLVMArrayTypeKind));
 	return OdinLLVMGetInternalElementType(type);
 	return OdinLLVMGetInternalElementType(type);
 }
 }
-LLVMTypeRef OdinLLVMGetVectorElementType(LLVMTypeRef type) {
+gb_internal LLVMTypeRef OdinLLVMGetVectorElementType(LLVMTypeRef type) {
 	GB_ASSERT(lb_is_type_kind(type, LLVMVectorTypeKind));
 	GB_ASSERT(lb_is_type_kind(type, LLVMVectorTypeKind));
 	return OdinLLVMGetInternalElementType(type);
 	return OdinLLVMGetInternalElementType(type);
 }
 }
 
 
 
 
-LLVMValueRef OdinLLVMBuildTransmute(lbProcedure *p, LLVMValueRef val, LLVMTypeRef dst_type) {
+gb_internal LLVMValueRef OdinLLVMBuildTransmute(lbProcedure *p, LLVMValueRef val, LLVMTypeRef dst_type) {
 	LLVMContextRef ctx = p->module->ctx;
 	LLVMContextRef ctx = p->module->ctx;
 	LLVMTypeRef src_type = LLVMTypeOf(val);
 	LLVMTypeRef src_type = LLVMTypeOf(val);
 
 
@@ -2445,7 +2413,7 @@ general_end:;
 
 
 
 
 
 
-LLVMValueRef lb_find_or_add_entity_string_ptr(lbModule *m, String const &str) {
+gb_internal LLVMValueRef lb_find_or_add_entity_string_ptr(lbModule *m, String const &str) {
 	StringHashKey key = string_hash_string(str);
 	StringHashKey key = string_hash_string(str);
 	LLVMValueRef *found = string_map_get(&m->const_strings, key);
 	LLVMValueRef *found = string_map_get(&m->const_strings, key);
 	if (found != nullptr) {
 	if (found != nullptr) {
@@ -2477,7 +2445,7 @@ LLVMValueRef lb_find_or_add_entity_string_ptr(lbModule *m, String const &str) {
 	}
 	}
 }
 }
 
 
-lbValue lb_find_or_add_entity_string(lbModule *m, String const &str) {
+gb_internal lbValue lb_find_or_add_entity_string(lbModule *m, String const &str) {
 	LLVMValueRef ptr = nullptr;
 	LLVMValueRef ptr = nullptr;
 	if (str.len != 0) {
 	if (str.len != 0) {
 		ptr = lb_find_or_add_entity_string_ptr(m, str);
 		ptr = lb_find_or_add_entity_string_ptr(m, str);
@@ -2493,43 +2461,7 @@ lbValue lb_find_or_add_entity_string(lbModule *m, String const &str) {
 	return res;
 	return res;
 }
 }
 
 
-lbValue lb_find_or_add_entity_string_byte_slice(lbModule *m, String const &str) {
-	LLVMValueRef indices[2] = {llvm_zero(m), llvm_zero(m)};
-	LLVMValueRef data = LLVMConstStringInContext(m->ctx,
-		cast(char const *)str.text,
-		cast(unsigned)str.len,
-		false);
-
-
-	char *name = nullptr;
-	{
-		isize max_len = 7+8+1;
-		name = gb_alloc_array(permanent_allocator(), char, max_len);
-		u32 id = m->gen->global_array_index.fetch_add(1);
-		isize len = gb_snprintf(name, max_len, "csbs$%x", id);
-		len -= 1;
-	}
-	LLVMTypeRef type = LLVMTypeOf(data);
-	LLVMValueRef global_data = LLVMAddGlobal(m->mod, type, name);
-	LLVMSetInitializer(global_data, data);
-	lb_make_global_private_const(global_data);
-	LLVMSetAlignment(global_data, 1);
-
-	LLVMValueRef ptr = nullptr;
-	if (str.len != 0) {
-		ptr = LLVMConstInBoundsGEP2(type, global_data, indices, 2);
-	} else {
-		ptr = LLVMConstNull(lb_type(m, t_u8_ptr));
-	}
-	LLVMValueRef len = LLVMConstInt(lb_type(m, t_int), str.len, true);
-	LLVMValueRef values[2] = {ptr, len};
-
-	lbValue res = {};
-	res.value = llvm_const_named_struct(m, t_u8_slice, values, 2);
-	res.type = t_u8_slice;
-	return res;
-}
-lbValue lb_find_or_add_entity_string_byte_slice_with_type(lbModule *m, String const &str, Type *slice_type) {
+gb_internal lbValue lb_find_or_add_entity_string_byte_slice_with_type(lbModule *m, String const &str, Type *slice_type) {
 	GB_ASSERT(is_type_slice(slice_type));
 	GB_ASSERT(is_type_slice(slice_type));
 	LLVMValueRef indices[2] = {llvm_zero(m), llvm_zero(m)};
 	LLVMValueRef indices[2] = {llvm_zero(m), llvm_zero(m)};
 	LLVMValueRef data = LLVMConstStringInContext(m->ctx,
 	LLVMValueRef data = LLVMConstStringInContext(m->ctx,
@@ -2579,7 +2511,7 @@ lbValue lb_find_or_add_entity_string_byte_slice_with_type(lbModule *m, String co
 
 
 
 
 
 
-lbValue lb_find_ident(lbProcedure *p, lbModule *m, Entity *e, Ast *expr) {
+gb_internal lbValue lb_find_ident(lbProcedure *p, lbModule *m, Entity *e, Ast *expr) {
 	if (e->flags & EntityFlag_Param) {
 	if (e->flags & EntityFlag_Param) {
 		// NOTE(bill): Bypass the stack copied variable for
 		// NOTE(bill): Bypass the stack copied variable for
 		// direct parameters as there is no need for the direct load
 		// direct parameters as there is no need for the direct load
@@ -2633,7 +2565,7 @@ lbValue lb_find_ident(lbProcedure *p, lbModule *m, Entity *e, Ast *expr) {
 }
 }
 
 
 
 
-lbValue lb_find_procedure_value_from_entity(lbModule *m, Entity *e) {
+gb_internal lbValue lb_find_procedure_value_from_entity(lbModule *m, Entity *e) {
 	GB_ASSERT(is_type_proc(e->type));
 	GB_ASSERT(is_type_proc(e->type));
 	e = strip_entity_wrapping(e);
 	e = strip_entity_wrapping(e);
 	GB_ASSERT(e != nullptr);
 	GB_ASSERT(e != nullptr);
@@ -2668,7 +2600,7 @@ lbValue lb_find_procedure_value_from_entity(lbModule *m, Entity *e) {
 }
 }
 
 
 
 
-lbAddr lb_add_global_generated(lbModule *m, Type *type, lbValue value, Entity **entity_) {
+gb_internal lbAddr lb_add_global_generated(lbModule *m, Type *type, lbValue value, Entity **entity_) {
 	GB_ASSERT(type != nullptr);
 	GB_ASSERT(type != nullptr);
 	type = default_type(type);
 	type = default_type(type);
 
 
@@ -2700,23 +2632,23 @@ lbAddr lb_add_global_generated(lbModule *m, Type *type, lbValue value, Entity **
 	return lb_addr(g);
 	return lb_addr(g);
 }
 }
 
 
-lbValue lb_find_runtime_value(lbModule *m, String const &name) {
+gb_internal lbValue lb_find_runtime_value(lbModule *m, String const &name) {
 	AstPackage *p = m->info->runtime_package;
 	AstPackage *p = m->info->runtime_package;
 	Entity *e = scope_lookup_current(p->scope, name);
 	Entity *e = scope_lookup_current(p->scope, name);
 	return lb_find_value_from_entity(m, e);
 	return lb_find_value_from_entity(m, e);
 }
 }
-lbValue lb_find_package_value(lbModule *m, String const &pkg, String const &name) {
+gb_internal lbValue lb_find_package_value(lbModule *m, String const &pkg, String const &name) {
 	Entity *e = find_entity_in_pkg(m->info, pkg, name);
 	Entity *e = find_entity_in_pkg(m->info, pkg, name);
 	return lb_find_value_from_entity(m, e);
 	return lb_find_value_from_entity(m, e);
 }
 }
 
 
-lbValue lb_generate_local_array(lbProcedure *p, Type *elem_type, i64 count, bool zero_init) {
+gb_internal lbValue lb_generate_local_array(lbProcedure *p, Type *elem_type, i64 count, bool zero_init) {
 	lbAddr addr = lb_add_local_generated(p, alloc_type_array(elem_type, count), zero_init);
 	lbAddr addr = lb_add_local_generated(p, alloc_type_array(elem_type, count), zero_init);
 	return lb_addr_get_ptr(p, addr);
 	return lb_addr_get_ptr(p, addr);
 }
 }
 
 
 
 
-lbValue lb_find_value_from_entity(lbModule *m, Entity *e) {
+gb_internal lbValue lb_find_value_from_entity(lbModule *m, Entity *e) {
 	e = strip_entity_wrapping(e);
 	e = strip_entity_wrapping(e);
 	GB_ASSERT(e != nullptr);
 	GB_ASSERT(e != nullptr);
 
 
@@ -2788,7 +2720,7 @@ lbValue lb_find_value_from_entity(lbModule *m, Entity *e) {
 	return {};
 	return {};
 }
 }
 
 
-lbValue lb_generate_global_array(lbModule *m, Type *elem_type, i64 count, String prefix, i64 id) {
+gb_internal lbValue lb_generate_global_array(lbModule *m, Type *elem_type, i64 count, String prefix, i64 id) {
 	Token token = {Token_Ident};
 	Token token = {Token_Ident};
 	isize name_len = prefix.len + 1 + 20;
 	isize name_len = prefix.len + 1 + 20;
 
 
@@ -2813,7 +2745,7 @@ lbValue lb_generate_global_array(lbModule *m, Type *elem_type, i64 count, String
 
 
 
 
 
 
-lbValue lb_build_cond(lbProcedure *p, Ast *cond, lbBlock *true_block, lbBlock *false_block) {
+gb_internal lbValue lb_build_cond(lbProcedure *p, Ast *cond, lbBlock *true_block, lbBlock *false_block) {
 	GB_ASSERT(cond != nullptr);
 	GB_ASSERT(cond != nullptr);
 	GB_ASSERT(true_block  != nullptr);
 	GB_ASSERT(true_block  != nullptr);
 	GB_ASSERT(false_block != nullptr);
 	GB_ASSERT(false_block != nullptr);
@@ -2868,7 +2800,7 @@ lbValue lb_build_cond(lbProcedure *p, Ast *cond, lbBlock *true_block, lbBlock *f
 }
 }
 
 
 
 
-lbAddr lb_add_local(lbProcedure *p, Type *type, Entity *e, bool zero_init, bool force_no_init) {
+gb_internal lbAddr lb_add_local(lbProcedure *p, Type *type, Entity *e, bool zero_init, bool force_no_init) {
 	GB_ASSERT(p->decl_block != p->curr_block);
 	GB_ASSERT(p->decl_block != p->curr_block);
 	LLVMPositionBuilderAtEnd(p->builder, p->decl_block->block);
 	LLVMPositionBuilderAtEnd(p->builder, p->decl_block->block);
 
 
@@ -2917,18 +2849,18 @@ lbAddr lb_add_local(lbProcedure *p, Type *type, Entity *e, bool zero_init, bool
 	return lb_addr(val);
 	return lb_addr(val);
 }
 }
 
 
-lbAddr lb_add_local_generated(lbProcedure *p, Type *type, bool zero_init) {
+gb_internal lbAddr lb_add_local_generated(lbProcedure *p, Type *type, bool zero_init) {
 	return lb_add_local(p, type, nullptr, zero_init);
 	return lb_add_local(p, type, nullptr, zero_init);
 }
 }
 
 
-lbAddr lb_add_local_generated_temp(lbProcedure *p, Type *type, i64 min_alignment) {
+gb_internal lbAddr lb_add_local_generated_temp(lbProcedure *p, Type *type, i64 min_alignment) {
 	lbAddr res = lb_add_local(p, type, nullptr, false, true);
 	lbAddr res = lb_add_local(p, type, nullptr, false, true);
 	lb_try_update_alignment(res.addr, cast(unsigned)min_alignment);
 	lb_try_update_alignment(res.addr, cast(unsigned)min_alignment);
 	return res;
 	return res;
 }
 }
 
 
 
 
-void lb_set_linkage_from_entity_flags(lbModule *m, LLVMValueRef value, u64 flags) {
+gb_internal void lb_set_linkage_from_entity_flags(lbModule *m, LLVMValueRef value, u64 flags) {
 	if (flags & EntityFlag_CustomLinkage_Internal) {
 	if (flags & EntityFlag_CustomLinkage_Internal) {
 		LLVMSetLinkage(value, LLVMInternalLinkage);
 		LLVMSetLinkage(value, LLVMInternalLinkage);
 	} else if (flags & EntityFlag_CustomLinkage_Strong) {
 	} else if (flags & EntityFlag_CustomLinkage_Strong) {

+ 26 - 26
src/llvm_backend_opt.cpp

@@ -32,21 +32,21 @@
 **************************************************************************/
 **************************************************************************/
 
 
 
 
-void lb_populate_function_pass_manager(lbModule *m, LLVMPassManagerRef fpm, bool ignore_memcpy_pass, i32 optimization_level);
-void lb_add_function_simplifcation_passes(LLVMPassManagerRef mpm, i32 optimization_level);
-void lb_populate_module_pass_manager(LLVMTargetMachineRef target_machine, LLVMPassManagerRef mpm, i32 optimization_level);
-void lb_populate_function_pass_manager_specific(lbModule *m, LLVMPassManagerRef fpm, i32 optimization_level);
-
-LLVMBool lb_must_preserve_predicate_callback(LLVMValueRef value, void *user_data) {
-	lbModule *m = cast(lbModule *)user_data;
-	if (m == nullptr) {
-		return false;
-	}
-	if (value == nullptr) {
-		return false;
-	}
-	return LLVMIsAAllocaInst(value) != nullptr;
-}
+gb_internal void lb_populate_function_pass_manager(lbModule *m, LLVMPassManagerRef fpm, bool ignore_memcpy_pass, i32 optimization_level);
+gb_internal void lb_add_function_simplifcation_passes(LLVMPassManagerRef mpm, i32 optimization_level);
+gb_internal void lb_populate_module_pass_manager(LLVMTargetMachineRef target_machine, LLVMPassManagerRef mpm, i32 optimization_level);
+gb_internal void lb_populate_function_pass_manager_specific(lbModule *m, LLVMPassManagerRef fpm, i32 optimization_level);
+
+// gb_internal LLVMBool lb_must_preserve_predicate_callback(LLVMValueRef value, void *user_data) {
+// 	lbModule *m = cast(lbModule *)user_data;
+// 	if (m == nullptr) {
+// 		return false;
+// 	}
+// 	if (value == nullptr) {
+// 		return false;
+// 	}
+// 	return LLVMIsAAllocaInst(value) != nullptr;
+// }
 
 
 
 
 #if LLVM_VERSION_MAJOR < 12
 #if LLVM_VERSION_MAJOR < 12
@@ -55,7 +55,7 @@ LLVMBool lb_must_preserve_predicate_callback(LLVMValueRef value, void *user_data
 #define LLVM_ADD_CONSTANT_VALUE_PASS(fpm) 
 #define LLVM_ADD_CONSTANT_VALUE_PASS(fpm) 
 #endif
 #endif
 
 
-void lb_basic_populate_function_pass_manager(LLVMPassManagerRef fpm, i32 optimization_level) {
+gb_internal void lb_basic_populate_function_pass_manager(LLVMPassManagerRef fpm, i32 optimization_level) {
 	if (false && optimization_level == 0 && build_context.ODIN_DEBUG) {
 	if (false && optimization_level == 0 && build_context.ODIN_DEBUG) {
 		LLVMAddMergedLoadStoreMotionPass(fpm);
 		LLVMAddMergedLoadStoreMotionPass(fpm);
 	} else {
 	} else {
@@ -68,7 +68,7 @@ void lb_basic_populate_function_pass_manager(LLVMPassManagerRef fpm, i32 optimiz
 	}
 	}
 }
 }
 
 
-void lb_populate_function_pass_manager(lbModule *m, LLVMPassManagerRef fpm, bool ignore_memcpy_pass, i32 optimization_level) {
+gb_internal void lb_populate_function_pass_manager(lbModule *m, LLVMPassManagerRef fpm, bool ignore_memcpy_pass, i32 optimization_level) {
 	// NOTE(bill): Treat -opt:3 as if it was -opt:2
 	// NOTE(bill): Treat -opt:3 as if it was -opt:2
 	// TODO(bill): Determine which opt definitions should exist in the first place
 	// TODO(bill): Determine which opt definitions should exist in the first place
 	optimization_level = gb_clamp(optimization_level, 0, 2);
 	optimization_level = gb_clamp(optimization_level, 0, 2);
@@ -102,7 +102,7 @@ void lb_populate_function_pass_manager(lbModule *m, LLVMPassManagerRef fpm, bool
 #endif
 #endif
 }
 }
 
 
-void lb_populate_function_pass_manager_specific(lbModule *m, LLVMPassManagerRef fpm, i32 optimization_level) {
+gb_internal void lb_populate_function_pass_manager_specific(lbModule *m, LLVMPassManagerRef fpm, i32 optimization_level) {
 	// NOTE(bill): Treat -opt:3 as if it was -opt:2
 	// NOTE(bill): Treat -opt:3 as if it was -opt:2
 	// TODO(bill): Determine which opt definitions should exist in the first place
 	// TODO(bill): Determine which opt definitions should exist in the first place
 	optimization_level = gb_clamp(optimization_level, 0, 2);
 	optimization_level = gb_clamp(optimization_level, 0, 2);
@@ -141,7 +141,7 @@ void lb_populate_function_pass_manager_specific(lbModule *m, LLVMPassManagerRef
 #endif
 #endif
 }
 }
 
 
-void lb_add_function_simplifcation_passes(LLVMPassManagerRef mpm, i32 optimization_level) {
+gb_internal void lb_add_function_simplifcation_passes(LLVMPassManagerRef mpm, i32 optimization_level) {
 	LLVMAddCFGSimplificationPass(mpm);
 	LLVMAddCFGSimplificationPass(mpm);
 
 
 	LLVMAddJumpThreadingPass(mpm);
 	LLVMAddJumpThreadingPass(mpm);
@@ -177,7 +177,7 @@ void lb_add_function_simplifcation_passes(LLVMPassManagerRef mpm, i32 optimizati
 }
 }
 
 
 
 
-void lb_populate_module_pass_manager(LLVMTargetMachineRef target_machine, LLVMPassManagerRef mpm, i32 optimization_level) {
+gb_internal void lb_populate_module_pass_manager(LLVMTargetMachineRef target_machine, LLVMPassManagerRef mpm, i32 optimization_level) {
 
 
 	// NOTE(bill): Treat -opt:3 as if it was -opt:2
 	// NOTE(bill): Treat -opt:3 as if it was -opt:2
 	// TODO(bill): Determine which opt definitions should exist in the first place
 	// TODO(bill): Determine which opt definitions should exist in the first place
@@ -266,7 +266,7 @@ void lb_populate_module_pass_manager(LLVMTargetMachineRef target_machine, LLVMPa
 	optimization of Odin programs	
 	optimization of Odin programs	
 **************************************************************************/
 **************************************************************************/
 
 
-void lb_run_remove_dead_instruction_pass(lbProcedure *p) {
+gb_internal void lb_run_remove_dead_instruction_pass(lbProcedure *p) {
 	isize removal_count = 0;
 	isize removal_count = 0;
 	isize pass_count = 0;
 	isize pass_count = 0;
 	isize const max_pass_count = 10;
 	isize const max_pass_count = 10;
@@ -358,7 +358,7 @@ void lb_run_remove_dead_instruction_pass(lbProcedure *p) {
 }
 }
 
 
 
 
-void lb_run_function_pass_manager(LLVMPassManagerRef fpm, lbProcedure *p) {
+gb_internal void lb_run_function_pass_manager(LLVMPassManagerRef fpm, lbProcedure *p) {
 	LLVMRunFunctionPassManager(fpm, p->value);
 	LLVMRunFunctionPassManager(fpm, p->value);
 	// NOTE(bill): LLVMAddDCEPass doesn't seem to be exported in the official DLL's for LLVM
 	// NOTE(bill): LLVMAddDCEPass doesn't seem to be exported in the official DLL's for LLVM
 	// which means we cannot rely upon it
 	// which means we cannot rely upon it
@@ -367,7 +367,7 @@ void lb_run_function_pass_manager(LLVMPassManagerRef fpm, lbProcedure *p) {
 	lb_run_remove_dead_instruction_pass(p);
 	lb_run_remove_dead_instruction_pass(p);
 }
 }
 
 
-void llvm_delete_function(LLVMValueRef func) {
+gb_internal void llvm_delete_function(LLVMValueRef func) {
 	// for (LLVMBasicBlockRef block = LLVMGetFirstBasicBlock(func); block != nullptr; /**/) {
 	// for (LLVMBasicBlockRef block = LLVMGetFirstBasicBlock(func); block != nullptr; /**/) {
 	// 	LLVMBasicBlockRef curr_block = block;
 	// 	LLVMBasicBlockRef curr_block = block;
 	// 	block = LLVMGetNextBasicBlock(block);
 	// 	block = LLVMGetNextBasicBlock(block);
@@ -382,7 +382,7 @@ void llvm_delete_function(LLVMValueRef func) {
 	LLVMDeleteFunction(func);
 	LLVMDeleteFunction(func);
 }
 }
 
 
-void lb_append_to_compiler_used(lbModule *m, LLVMValueRef func) {
+gb_internal void lb_append_to_compiler_used(lbModule *m, LLVMValueRef func) {
 	LLVMValueRef global = LLVMGetNamedGlobal(m->mod, "llvm.compiler.used");
 	LLVMValueRef global = LLVMGetNamedGlobal(m->mod, "llvm.compiler.used");
 
 
 	LLVMValueRef *constants;
 	LLVMValueRef *constants;
@@ -419,7 +419,7 @@ void lb_append_to_compiler_used(lbModule *m, LLVMValueRef func) {
 	LLVMSetInitializer(global, initializer);
 	LLVMSetInitializer(global, initializer);
 }
 }
 
 
-void lb_run_remove_unused_function_pass(lbModule *m) {
+gb_internal void lb_run_remove_unused_function_pass(lbModule *m) {
 	isize removal_count = 0;
 	isize removal_count = 0;
 	isize pass_count = 0;
 	isize pass_count = 0;
 	isize const max_pass_count = 10;
 	isize const max_pass_count = 10;
@@ -470,7 +470,7 @@ void lb_run_remove_unused_function_pass(lbModule *m) {
 }
 }
 
 
 
 
-void lb_run_remove_unused_globals_pass(lbModule *m) {
+gb_internal void lb_run_remove_unused_globals_pass(lbModule *m) {
 	isize removal_count = 0;
 	isize removal_count = 0;
 	isize pass_count = 0;
 	isize pass_count = 0;
 	isize const max_pass_count = 10;
 	isize const max_pass_count = 10;

+ 68 - 77
src/llvm_backend_proc.cpp

@@ -1,5 +1,4 @@
-LLVMValueRef lb_call_intrinsic(lbProcedure *p, const char *name, LLVMValueRef* args, unsigned arg_count, LLVMTypeRef* types, unsigned type_count)
-{
+gb_internal LLVMValueRef lb_call_intrinsic(lbProcedure *p, const char *name, LLVMValueRef* args, unsigned arg_count, LLVMTypeRef* types, unsigned type_count) {
 	unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
 	unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
 	GB_ASSERT_MSG(id != 0, "Unable to find %s", name);
 	GB_ASSERT_MSG(id != 0, "Unable to find %s", name);
 	LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, type_count);
 	LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, type_count);
@@ -7,7 +6,7 @@ LLVMValueRef lb_call_intrinsic(lbProcedure *p, const char *name, LLVMValueRef* a
 	return LLVMBuildCall2(p->builder, call_type, ip, args, arg_count, "");
 	return LLVMBuildCall2(p->builder, call_type, ip, args, arg_count, "");
 }
 }
 
 
-void lb_mem_copy_overlapping(lbProcedure *p, lbValue dst, lbValue src, lbValue len, bool is_volatile) {
+gb_internal void lb_mem_copy_overlapping(lbProcedure *p, lbValue dst, lbValue src, lbValue len, bool is_volatile) {
 	dst = lb_emit_conv(p, dst, t_rawptr);
 	dst = lb_emit_conv(p, dst, t_rawptr);
 	src = lb_emit_conv(p, src, t_rawptr);
 	src = lb_emit_conv(p, src, t_rawptr);
 	len = lb_emit_conv(p, len, t_int);
 	len = lb_emit_conv(p, len, t_int);
@@ -36,7 +35,7 @@ void lb_mem_copy_overlapping(lbProcedure *p, lbValue dst, lbValue src, lbValue l
 
 
 
 
 
 
-void lb_mem_copy_non_overlapping(lbProcedure *p, lbValue dst, lbValue src, lbValue len, bool is_volatile) {
+gb_internal void lb_mem_copy_non_overlapping(lbProcedure *p, lbValue dst, lbValue src, lbValue len, bool is_volatile) {
 	dst = lb_emit_conv(p, dst, t_rawptr);
 	dst = lb_emit_conv(p, dst, t_rawptr);
 	src = lb_emit_conv(p, src, t_rawptr);
 	src = lb_emit_conv(p, src, t_rawptr);
 	len = lb_emit_conv(p, len, t_int);
 	len = lb_emit_conv(p, len, t_int);
@@ -65,7 +64,7 @@ void lb_mem_copy_non_overlapping(lbProcedure *p, lbValue dst, lbValue src, lbVal
 }
 }
 
 
 
 
-lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool ignore_body) {
+gb_internal lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool ignore_body) {
 	GB_ASSERT(entity != nullptr);
 	GB_ASSERT(entity != nullptr);
 	GB_ASSERT(entity->kind == Entity_Procedure);
 	GB_ASSERT(entity->kind == Entity_Procedure);
 	if (!entity->Procedure.is_foreign) {
 	if (!entity->Procedure.is_foreign) {
@@ -320,7 +319,7 @@ lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool ignore_body)
 	return p;
 	return p;
 }
 }
 
 
-lbProcedure *lb_create_dummy_procedure(lbModule *m, String link_name, Type *type) {
+gb_internal lbProcedure *lb_create_dummy_procedure(lbModule *m, String link_name, Type *type) {
 	{
 	{
 		lbValue *found = string_map_get(&m->members, link_name);
 		lbValue *found = string_map_get(&m->members, link_name);
 		GB_ASSERT_MSG(found == nullptr, "failed to create dummy procedure for: %.*s", LIT(link_name));
 		GB_ASSERT_MSG(found == nullptr, "failed to create dummy procedure for: %.*s", LIT(link_name));
@@ -384,50 +383,50 @@ lbProcedure *lb_create_dummy_procedure(lbModule *m, String link_name, Type *type
 }
 }
 
 
 
 
-lbValue lb_value_param(lbProcedure *p, Entity *e, Type *abi_type, i32 index, lbParamPasskind *kind_) {
-	lbParamPasskind kind = lbParamPass_Value;
-
-	if (e != nullptr && !are_types_identical(abi_type, e->type)) {
-		if (is_type_pointer(abi_type)) {
-			GB_ASSERT(e->kind == Entity_Variable);
-			Type *av = core_type(type_deref(abi_type));
-			if (are_types_identical(av, core_type(e->type))) {
-				kind = lbParamPass_Pointer;
-				if (e->flags&EntityFlag_Value) {
-					kind = lbParamPass_ConstRef;
-				}
-			} else {
-				kind = lbParamPass_BitCast;
-			}
-		} else if (is_type_integer(abi_type)) {
-			kind = lbParamPass_Integer;
-		} else if (abi_type == t_llvm_bool) {
-			kind = lbParamPass_Value;
-		} else if (is_type_boolean(abi_type)) {
-			kind = lbParamPass_Integer;
-		} else if (is_type_simd_vector(abi_type)) {
-			kind = lbParamPass_BitCast;
-		} else if (is_type_float(abi_type)) {
-			kind = lbParamPass_BitCast;
-		} else if (is_type_tuple(abi_type)) {
-			kind = lbParamPass_Tuple;
-		} else if (is_type_proc(abi_type)) {
-			kind = lbParamPass_Value;
-		} else {
-			GB_PANIC("Invalid abi type pass kind %s", type_to_string(abi_type));
-		}
-	}
-
-	if (kind_) *kind_ = kind;
-	lbValue res = {};
-	res.value = LLVMGetParam(p->value, cast(unsigned)index);
-	res.type = abi_type;
-	return res;
-}
-
-
-
-void lb_start_block(lbProcedure *p, lbBlock *b) {
+// gb_internal lbValue lb_value_param(lbProcedure *p, Entity *e, Type *abi_type, i32 index, lbParamPasskind *kind_) {
+// 	lbParamPasskind kind = lbParamPass_Value;
+
+// 	if (e != nullptr && !are_types_identical(abi_type, e->type)) {
+// 		if (is_type_pointer(abi_type)) {
+// 			GB_ASSERT(e->kind == Entity_Variable);
+// 			Type *av = core_type(type_deref(abi_type));
+// 			if (are_types_identical(av, core_type(e->type))) {
+// 				kind = lbParamPass_Pointer;
+// 				if (e->flags&EntityFlag_Value) {
+// 					kind = lbParamPass_ConstRef;
+// 				}
+// 			} else {
+// 				kind = lbParamPass_BitCast;
+// 			}
+// 		} else if (is_type_integer(abi_type)) {
+// 			kind = lbParamPass_Integer;
+// 		} else if (abi_type == t_llvm_bool) {
+// 			kind = lbParamPass_Value;
+// 		} else if (is_type_boolean(abi_type)) {
+// 			kind = lbParamPass_Integer;
+// 		} else if (is_type_simd_vector(abi_type)) {
+// 			kind = lbParamPass_BitCast;
+// 		} else if (is_type_float(abi_type)) {
+// 			kind = lbParamPass_BitCast;
+// 		} else if (is_type_tuple(abi_type)) {
+// 			kind = lbParamPass_Tuple;
+// 		} else if (is_type_proc(abi_type)) {
+// 			kind = lbParamPass_Value;
+// 		} else {
+// 			GB_PANIC("Invalid abi type pass kind %s", type_to_string(abi_type));
+// 		}
+// 	}
+
+// 	if (kind_) *kind_ = kind;
+// 	lbValue res = {};
+// 	res.value = LLVMGetParam(p->value, cast(unsigned)index);
+// 	res.type = abi_type;
+// 	return res;
+// }
+
+
+
+gb_internal void lb_start_block(lbProcedure *p, lbBlock *b) {
 	GB_ASSERT(b != nullptr);
 	GB_ASSERT(b != nullptr);
 	if (!b->appended) {
 	if (!b->appended) {
 		b->appended = true;
 		b->appended = true;
@@ -437,7 +436,7 @@ void lb_start_block(lbProcedure *p, lbBlock *b) {
 	p->curr_block = b;
 	p->curr_block = b;
 }
 }
 
 
-void lb_set_debug_position_to_procedure_begin(lbProcedure *p) {
+gb_internal void lb_set_debug_position_to_procedure_begin(lbProcedure *p) {
 	if (p->debug_info == nullptr) {
 	if (p->debug_info == nullptr) {
 		return;
 		return;
 	}
 	}
@@ -454,7 +453,7 @@ void lb_set_debug_position_to_procedure_begin(lbProcedure *p) {
 	}
 	}
 }
 }
 
 
-void lb_set_debug_position_to_procedure_end(lbProcedure *p) {
+gb_internal void lb_set_debug_position_to_procedure_end(lbProcedure *p) {
 	if (p->debug_info == nullptr) {
 	if (p->debug_info == nullptr) {
 		return;
 		return;
 	}
 	}
@@ -471,7 +470,7 @@ void lb_set_debug_position_to_procedure_end(lbProcedure *p) {
 	}
 	}
 }
 }
 
 
-void lb_begin_procedure_body(lbProcedure *p) {
+gb_internal void lb_begin_procedure_body(lbProcedure *p) {
 	DeclInfo *decl = decl_info_of_entity(p->entity);
 	DeclInfo *decl = decl_info_of_entity(p->entity);
 	if (decl != nullptr) {
 	if (decl != nullptr) {
 		for_array(i, decl->labels) {
 		for_array(i, decl->labels) {
@@ -686,7 +685,7 @@ void lb_begin_procedure_body(lbProcedure *p) {
 	lb_start_block(p, p->entry_block);
 	lb_start_block(p, p->entry_block);
 }
 }
 
 
-void lb_end_procedure_body(lbProcedure *p) {
+gb_internal void lb_end_procedure_body(lbProcedure *p) {
 	lb_set_debug_position_to_procedure_begin(p);
 	lb_set_debug_position_to_procedure_begin(p);
 
 
 	LLVMPositionBuilderAtEnd(p->builder, p->decl_block->block);
 	LLVMPositionBuilderAtEnd(p->builder, p->decl_block->block);
@@ -720,11 +719,11 @@ void lb_end_procedure_body(lbProcedure *p) {
 	p->curr_block = nullptr;
 	p->curr_block = nullptr;
 	p->state_flags = 0;
 	p->state_flags = 0;
 }
 }
-void lb_end_procedure(lbProcedure *p) {
+gb_internal void lb_end_procedure(lbProcedure *p) {
 	LLVMDisposeBuilder(p->builder);
 	LLVMDisposeBuilder(p->builder);
 }
 }
 
 
-void lb_build_nested_proc(lbProcedure *p, AstProcLit *pd, Entity *e) {
+gb_internal void lb_build_nested_proc(lbProcedure *p, AstProcLit *pd, Entity *e) {
 	GB_ASSERT(pd->body != nullptr);
 	GB_ASSERT(pd->body != nullptr);
 	lbModule *m = p->module;
 	lbModule *m = p->module;
 	auto *min_dep_set = &m->info->minimum_dependency_set;
 	auto *min_dep_set = &m->info->minimum_dependency_set;
@@ -766,7 +765,7 @@ void lb_build_nested_proc(lbProcedure *p, AstProcLit *pd, Entity *e) {
 
 
 
 
 
 
-Array<lbValue> lb_value_to_array(lbProcedure *p, lbValue value) {
+gb_internal Array<lbValue> lb_value_to_array(lbProcedure *p, lbValue value) {
 	Array<lbValue> array = {};
 	Array<lbValue> array = {};
 	Type *t = base_type(value.type);
 	Type *t = base_type(value.type);
 	if (t == nullptr) {
 	if (t == nullptr) {
@@ -783,7 +782,7 @@ Array<lbValue> lb_value_to_array(lbProcedure *p, lbValue value) {
 
 
 
 
 
 
-lbValue lb_emit_call_internal(lbProcedure *p, lbValue value, lbValue return_ptr, Array<lbValue> const &processed_args, Type *abi_rt, lbAddr context_ptr, ProcInlining inlining) {
+gb_internal lbValue lb_emit_call_internal(lbProcedure *p, lbValue value, lbValue return_ptr, Array<lbValue> const &processed_args, Type *abi_rt, lbAddr context_ptr, ProcInlining inlining) {
 	GB_ASSERT(p->module->ctx == LLVMGetTypeContext(LLVMTypeOf(value.value)));
 	GB_ASSERT(p->module->ctx == LLVMGetTypeContext(LLVMTypeOf(value.value)));
 
 
 	unsigned arg_count = cast(unsigned)processed_args.count;
 	unsigned arg_count = cast(unsigned)processed_args.count;
@@ -892,20 +891,20 @@ lbValue lb_emit_call_internal(lbProcedure *p, lbValue value, lbValue return_ptr,
 }
 }
 
 
 
 
-lbValue lb_lookup_runtime_procedure(lbModule *m, String const &name) {
+gb_internal lbValue lb_lookup_runtime_procedure(lbModule *m, String const &name) {
 	AstPackage *pkg = m->info->runtime_package;
 	AstPackage *pkg = m->info->runtime_package;
 	Entity *e = scope_lookup_current(pkg->scope, name);
 	Entity *e = scope_lookup_current(pkg->scope, name);
 	return lb_find_procedure_value_from_entity(m, e);
 	return lb_find_procedure_value_from_entity(m, e);
 }
 }
 
 
 
 
-lbValue lb_emit_runtime_call(lbProcedure *p, char const *c_name, Array<lbValue> const &args) {
+gb_internal lbValue lb_emit_runtime_call(lbProcedure *p, char const *c_name, Array<lbValue> const &args) {
 	String name = make_string_c(c_name);
 	String name = make_string_c(c_name);
 	lbValue proc = lb_lookup_runtime_procedure(p->module, name);
 	lbValue proc = lb_lookup_runtime_procedure(p->module, name);
 	return lb_emit_call(p, proc, args);
 	return lb_emit_call(p, proc, args);
 }
 }
 
 
-lbValue lb_emit_conjugate(lbProcedure *p, lbValue val, Type *type) {
+gb_internal lbValue lb_emit_conjugate(lbProcedure *p, lbValue val, Type *type) {
 	lbValue res = {};
 	lbValue res = {};
 	Type *t = val.type;
 	Type *t = val.type;
 	if (is_type_complex(t)) {
 	if (is_type_complex(t)) {
@@ -956,7 +955,7 @@ lbValue lb_emit_conjugate(lbProcedure *p, lbValue val, Type *type) {
 	return lb_emit_load(p, res);
 	return lb_emit_load(p, res);
 }
 }
 
 
-lbValue lb_emit_call(lbProcedure *p, lbValue value, Array<lbValue> const &args, ProcInlining inlining) {
+gb_internal lbValue lb_emit_call(lbProcedure *p, lbValue value, Array<lbValue> const &args, ProcInlining inlining) {
 	lbModule *m = p->module;
 	lbModule *m = p->module;
 
 
 	Type *pt = base_type(value.type);
 	Type *pt = base_type(value.type);
@@ -1166,15 +1165,7 @@ lbValue lb_emit_call(lbProcedure *p, lbValue value, Array<lbValue> const &args,
 	return result;
 	return result;
 }
 }
 
 
-LLVMValueRef llvm_splat_float(i64 count, LLVMTypeRef type, f64 value) {
-	LLVMValueRef v = LLVMConstReal(type, value);
-	LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, count);
-	for (i64 i = 0; i < count; i++) {
-		values[i] = v;
-	}
-	return LLVMConstVector(values, cast(unsigned)count);
-}
-LLVMValueRef llvm_splat_int(i64 count, LLVMTypeRef type, i64 value, bool is_signed=false) {
+gb_internal LLVMValueRef llvm_splat_int(i64 count, LLVMTypeRef type, i64 value, bool is_signed=false) {
 	LLVMValueRef v = LLVMConstInt(type, value, is_signed);
 	LLVMValueRef v = LLVMConstInt(type, value, is_signed);
 	LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, count);
 	LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, count);
 	for (i64 i = 0; i < count; i++) {
 	for (i64 i = 0; i < count; i++) {
@@ -1184,7 +1175,7 @@ LLVMValueRef llvm_splat_int(i64 count, LLVMTypeRef type, i64 value, bool is_sign
 }
 }
 
 
 
 
-lbValue lb_build_builtin_simd_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, BuiltinProcId builtin_id) {
+gb_internal lbValue lb_build_builtin_simd_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, BuiltinProcId builtin_id) {
 	ast_node(ce, CallExpr, expr);
 	ast_node(ce, CallExpr, expr);
 
 
 	lbModule *m = p->module;
 	lbModule *m = p->module;
@@ -1600,7 +1591,7 @@ lbValue lb_build_builtin_simd_proc(lbProcedure *p, Ast *expr, TypeAndValue const
 }
 }
 
 
 
 
-lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, BuiltinProcId id) {
+gb_internal lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, BuiltinProcId id) {
 	ast_node(ce, CallExpr, expr);
 	ast_node(ce, CallExpr, expr);
 
 
 	if (BuiltinProc__simd_begin < id && id < BuiltinProc__simd_end) {
 	if (BuiltinProc__simd_begin < id && id < BuiltinProc__simd_end) {
@@ -2980,7 +2971,7 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv,
 }
 }
 
 
 
 
-lbValue lb_handle_param_value(lbProcedure *p, Type *parameter_type, ParameterValue const &param_value, TokenPos const &pos) {
+gb_internal lbValue lb_handle_param_value(lbProcedure *p, Type *parameter_type, ParameterValue const &param_value, TokenPos const &pos) {
 	switch (param_value.kind) {
 	switch (param_value.kind) {
 	case ParameterValue_Constant:
 	case ParameterValue_Constant:
 		if (is_type_constant_type(parameter_type)) {
 		if (is_type_constant_type(parameter_type)) {
@@ -3015,9 +3006,9 @@ lbValue lb_handle_param_value(lbProcedure *p, Type *parameter_type, ParameterVal
 }
 }
 
 
 
 
-lbValue lb_build_call_expr_internal(lbProcedure *p, Ast *expr);
+gb_internal lbValue lb_build_call_expr_internal(lbProcedure *p, Ast *expr);
 
 
-lbValue lb_build_call_expr(lbProcedure *p, Ast *expr) {
+gb_internal lbValue lb_build_call_expr(lbProcedure *p, Ast *expr) {
 	expr = unparen_expr(expr);
 	expr = unparen_expr(expr);
 	ast_node(ce, CallExpr, expr);
 	ast_node(ce, CallExpr, expr);
 
 
@@ -3030,7 +3021,7 @@ lbValue lb_build_call_expr(lbProcedure *p, Ast *expr) {
 	}
 	}
 	return res;
 	return res;
 }
 }
-lbValue lb_build_call_expr_internal(lbProcedure *p, Ast *expr) {
+gb_internal lbValue lb_build_call_expr_internal(lbProcedure *p, Ast *expr) {
 	lbModule *m = p->module;
 	lbModule *m = p->module;
 
 
 	TypeAndValue tv = type_and_value_of_expr(expr);
 	TypeAndValue tv = type_and_value_of_expr(expr);

+ 44 - 54
src/llvm_backend_stmt.cpp

@@ -1,4 +1,4 @@
-void lb_build_constant_value_decl(lbProcedure *p, AstValueDecl *vd) {
+gb_internal void lb_build_constant_value_decl(lbProcedure *p, AstValueDecl *vd) {
 	if (vd == nullptr || vd->is_mutable) {
 	if (vd == nullptr || vd->is_mutable) {
 		return;
 		return;
 	}
 	}
@@ -105,7 +105,7 @@ void lb_build_constant_value_decl(lbProcedure *p, AstValueDecl *vd) {
 }
 }
 
 
 
 
-void lb_build_stmt_list(lbProcedure *p, Slice<Ast *> const &stmts) {
+gb_internal void lb_build_stmt_list(lbProcedure *p, Slice<Ast *> const &stmts) {
 	for_array(i, stmts) {
 	for_array(i, stmts) {
 		Ast *stmt = stmts[i];
 		Ast *stmt = stmts[i];
 		switch (stmt->kind) {
 		switch (stmt->kind) {
@@ -125,7 +125,7 @@ void lb_build_stmt_list(lbProcedure *p, Slice<Ast *> const &stmts) {
 
 
 
 
 
 
-lbBranchBlocks lb_lookup_branch_blocks(lbProcedure *p, Ast *ident) {
+gb_internal lbBranchBlocks lb_lookup_branch_blocks(lbProcedure *p, Ast *ident) {
 	GB_ASSERT(ident->kind == Ast_Ident);
 	GB_ASSERT(ident->kind == Ast_Ident);
 	Entity *e = entity_of_node(ident);
 	Entity *e = entity_of_node(ident);
 	GB_ASSERT(e->kind == Entity_Label);
 	GB_ASSERT(e->kind == Entity_Label);
@@ -142,7 +142,7 @@ lbBranchBlocks lb_lookup_branch_blocks(lbProcedure *p, Ast *ident) {
 }
 }
 
 
 
 
-lbTargetList *lb_push_target_list(lbProcedure *p, Ast *label, lbBlock *break_, lbBlock *continue_, lbBlock *fallthrough_) {
+gb_internal lbTargetList *lb_push_target_list(lbProcedure *p, Ast *label, lbBlock *break_, lbBlock *continue_, lbBlock *fallthrough_) {
 	lbTargetList *tl = gb_alloc_item(permanent_allocator(), lbTargetList);
 	lbTargetList *tl = gb_alloc_item(permanent_allocator(), lbTargetList);
 	tl->prev = p->target_list;
 	tl->prev = p->target_list;
 	tl->break_ = break_;
 	tl->break_ = break_;
@@ -170,11 +170,11 @@ lbTargetList *lb_push_target_list(lbProcedure *p, Ast *label, lbBlock *break_, l
 	return tl;
 	return tl;
 }
 }
 
 
-void lb_pop_target_list(lbProcedure *p) {
+gb_internal void lb_pop_target_list(lbProcedure *p) {
 	p->target_list = p->target_list->prev;
 	p->target_list = p->target_list->prev;
 }
 }
 
 
-void lb_open_scope(lbProcedure *p, Scope *s) {
+gb_internal void lb_open_scope(lbProcedure *p, Scope *s) {
 	lbModule *m = p->module;
 	lbModule *m = p->module;
 	if (m->debug_builder) {
 	if (m->debug_builder) {
 		LLVMMetadataRef curr_metadata = lb_get_llvm_metadata(m, s);
 		LLVMMetadataRef curr_metadata = lb_get_llvm_metadata(m, s);
@@ -211,7 +211,7 @@ void lb_open_scope(lbProcedure *p, Scope *s) {
 
 
 }
 }
 
 
-void lb_close_scope(lbProcedure *p, lbDeferExitKind kind, lbBlock *block, bool pop_stack=true) {
+gb_internal void lb_close_scope(lbProcedure *p, lbDeferExitKind kind, lbBlock *block, bool pop_stack=true) {
 	lb_emit_defer_stmts(p, kind, block);
 	lb_emit_defer_stmts(p, kind, block);
 	GB_ASSERT(p->scope_index > 0);
 	GB_ASSERT(p->scope_index > 0);
 
 
@@ -230,7 +230,7 @@ void lb_close_scope(lbProcedure *p, lbDeferExitKind kind, lbBlock *block, bool p
 	array_pop(&p->scope_stack);
 	array_pop(&p->scope_stack);
 }
 }
 
 
-void lb_build_when_stmt(lbProcedure *p, AstWhenStmt *ws) {
+gb_internal void lb_build_when_stmt(lbProcedure *p, AstWhenStmt *ws) {
 	TypeAndValue tv = type_and_value_of_expr(ws->cond);
 	TypeAndValue tv = type_and_value_of_expr(ws->cond);
 	GB_ASSERT(is_type_boolean(tv.type));
 	GB_ASSERT(is_type_boolean(tv.type));
 	GB_ASSERT(tv.value.kind == ExactValue_Bool);
 	GB_ASSERT(tv.value.kind == ExactValue_Bool);
@@ -253,8 +253,8 @@ void lb_build_when_stmt(lbProcedure *p, AstWhenStmt *ws) {
 
 
 
 
 
 
-void lb_build_range_indexed(lbProcedure *p, lbValue expr, Type *val_type, lbValue count_ptr,
-                            lbValue *val_, lbValue *idx_, lbBlock **loop_, lbBlock **done_) {
+gb_internal void lb_build_range_indexed(lbProcedure *p, lbValue expr, Type *val_type, lbValue count_ptr,
+                                        lbValue *val_, lbValue *idx_, lbBlock **loop_, lbBlock **done_) {
 	lbModule *m = p->module;
 	lbModule *m = p->module;
 
 
 	lbValue count = {};
 	lbValue count = {};
@@ -342,7 +342,7 @@ void lb_build_range_indexed(lbProcedure *p, lbValue expr, Type *val_type, lbValu
 	if (done_) *done_ = done;
 	if (done_) *done_ = done;
 }
 }
 
 
-lbValue lb_map_cell_index_static(lbProcedure *p, Type *type, lbValue cells_ptr, lbValue index) {
+gb_internal lbValue lb_map_cell_index_static(lbProcedure *p, Type *type, lbValue cells_ptr, lbValue index) {
 	i64 size, len;
 	i64 size, len;
 	i64 elem_sz = type_size_of(type);
 	i64 elem_sz = type_size_of(type);
 	map_cell_size_and_len(type, &size, &len);
 	map_cell_size_and_len(type, &size, &len);
@@ -378,17 +378,7 @@ lbValue lb_map_cell_index_static(lbProcedure *p, Type *type, lbValue cells_ptr,
 	return lb_emit_ptr_offset(p, elems_ptr, data_index);
 	return lb_emit_ptr_offset(p, elems_ptr, data_index);
 }
 }
 
 
-void lb_map_kvh_data_static(lbProcedure *p, lbValue map_value, lbValue *ks_, lbValue *vs_, lbValue *hs_) {
-	lbValue capacity = lb_map_cap(p, map_value);
-	lbValue ks = lb_map_data_uintptr(p, map_value);
-	lbValue vs = {};
-	lbValue hs = {};
-	if (ks_) *ks_ = ks;
-	if (vs_) *vs_ = vs;
-	if (hs_) *hs_ = hs;
-}
-
-lbValue lb_map_hash_is_valid(lbProcedure *p, lbValue hash) {
+gb_internal lbValue lb_map_hash_is_valid(lbProcedure *p, lbValue hash) {
 	// N :: size_of(uintptr)*8 - 1
 	// N :: size_of(uintptr)*8 - 1
 	// (hash != 0) & (hash>>N == 0)
 	// (hash != 0) & (hash>>N == 0)
 
 
@@ -404,8 +394,8 @@ lbValue lb_map_hash_is_valid(lbProcedure *p, lbValue hash) {
 	return lb_emit_arith(p, Token_And, not_deleted, not_empty, t_uintptr);
 	return lb_emit_arith(p, Token_And, not_deleted, not_empty, t_uintptr);
 }
 }
 
 
-void lb_build_range_map(lbProcedure *p, lbValue expr, Type *val_type,
-                        lbValue *val_, lbValue *key_, lbBlock **loop_, lbBlock **done_) {
+gb_internal void lb_build_range_map(lbProcedure *p, lbValue expr, Type *val_type,
+                                    lbValue *val_, lbValue *key_, lbBlock **loop_, lbBlock **done_) {
 	lbModule *m = p->module;
 	lbModule *m = p->module;
 
 
 	Type *type = base_type(type_deref(expr.type));
 	Type *type = base_type(type_deref(expr.type));
@@ -466,8 +456,8 @@ void lb_build_range_map(lbProcedure *p, lbValue expr, Type *val_type,
 
 
 
 
 
 
-void lb_build_range_string(lbProcedure *p, lbValue expr, Type *val_type,
-                            lbValue *val_, lbValue *idx_, lbBlock **loop_, lbBlock **done_) {
+gb_internal void lb_build_range_string(lbProcedure *p, lbValue expr, Type *val_type,
+                                       lbValue *val_, lbValue *idx_, lbBlock **loop_, lbBlock **done_) {
 	lbModule *m = p->module;
 	lbModule *m = p->module;
 	lbValue count = lb_const_int(m, t_int, 0);
 	lbValue count = lb_const_int(m, t_int, 0);
 	Type *expr_type = base_type(expr.type);
 	Type *expr_type = base_type(expr.type);
@@ -526,8 +516,8 @@ void lb_build_range_string(lbProcedure *p, lbValue expr, Type *val_type,
 }
 }
 
 
 
 
-void lb_build_range_interval(lbProcedure *p, AstBinaryExpr *node,
-                             AstRangeStmt *rs, Scope *scope) {
+gb_internal void lb_build_range_interval(lbProcedure *p, AstBinaryExpr *node,
+                                         AstRangeStmt *rs, Scope *scope) {
 	bool ADD_EXTRA_WRAPPING_CHECK = true;
 	bool ADD_EXTRA_WRAPPING_CHECK = true;
 
 
 	lbModule *m = p->module;
 	lbModule *m = p->module;
@@ -630,7 +620,7 @@ void lb_build_range_interval(lbProcedure *p, AstBinaryExpr *node,
 	lb_start_block(p, done);
 	lb_start_block(p, done);
 }
 }
 
 
-void lb_build_range_enum(lbProcedure *p, Type *enum_type, Type *val_type, lbValue *val_, lbValue *idx_, lbBlock **loop_, lbBlock **done_) {
+gb_internal void lb_build_range_enum(lbProcedure *p, Type *enum_type, Type *val_type, lbValue *val_, lbValue *idx_, lbBlock **loop_, lbBlock **done_) {
 	lbModule *m = p->module;
 	lbModule *m = p->module;
 
 
 	Type *t = enum_type;
 	Type *t = enum_type;
@@ -683,8 +673,8 @@ void lb_build_range_enum(lbProcedure *p, Type *enum_type, Type *val_type, lbValu
 	if (done_) *done_ = done;
 	if (done_) *done_ = done;
 }
 }
 
 
-void lb_build_range_tuple(lbProcedure *p, Ast *expr, Type *val0_type, Type *val1_type,
-                          lbValue *val0_, lbValue *val1_, lbBlock **loop_, lbBlock **done_) {
+gb_internal void lb_build_range_tuple(lbProcedure *p, Ast *expr, Type *val0_type, Type *val1_type,
+                                      lbValue *val0_, lbValue *val1_, lbBlock **loop_, lbBlock **done_) {
 	lbBlock *loop = lb_create_block(p, "for.tuple.loop");
 	lbBlock *loop = lb_create_block(p, "for.tuple.loop");
 	lb_emit_jump(p, loop);
 	lb_emit_jump(p, loop);
 	lb_start_block(p, loop);
 	lb_start_block(p, loop);
@@ -709,7 +699,7 @@ void lb_build_range_tuple(lbProcedure *p, Ast *expr, Type *val0_type, Type *val1
 	if (done_) *done_ = done;
 	if (done_) *done_ = done;
 }
 }
 
 
-void lb_build_range_stmt_struct_soa(lbProcedure *p, AstRangeStmt *rs, Scope *scope) {
+gb_internal void lb_build_range_stmt_struct_soa(lbProcedure *p, AstRangeStmt *rs, Scope *scope) {
 	Ast *expr = unparen_expr(rs->expr);
 	Ast *expr = unparen_expr(rs->expr);
 	TypeAndValue tav = type_and_value_of_expr(expr);
 	TypeAndValue tav = type_and_value_of_expr(expr);
 
 
@@ -778,7 +768,7 @@ void lb_build_range_stmt_struct_soa(lbProcedure *p, AstRangeStmt *rs, Scope *sco
 
 
 }
 }
 
 
-void lb_build_range_stmt(lbProcedure *p, AstRangeStmt *rs, Scope *scope) {
+gb_internal void lb_build_range_stmt(lbProcedure *p, AstRangeStmt *rs, Scope *scope) {
 	Ast *expr = unparen_expr(rs->expr);
 	Ast *expr = unparen_expr(rs->expr);
 
 
 	if (is_ast_range(expr)) {
 	if (is_ast_range(expr)) {
@@ -923,7 +913,7 @@ void lb_build_range_stmt(lbProcedure *p, AstRangeStmt *rs, Scope *scope) {
 	lb_start_block(p, done);
 	lb_start_block(p, done);
 }
 }
 
 
-void lb_build_unroll_range_stmt(lbProcedure *p, AstUnrollRangeStmt *rs, Scope *scope) {
+gb_internal void lb_build_unroll_range_stmt(lbProcedure *p, AstUnrollRangeStmt *rs, Scope *scope) {
 	lbModule *m = p->module;
 	lbModule *m = p->module;
 
 
 	lb_open_scope(p, scope); // Open scope here
 	lb_open_scope(p, scope); // Open scope here
@@ -1089,7 +1079,7 @@ void lb_build_unroll_range_stmt(lbProcedure *p, AstUnrollRangeStmt *rs, Scope *s
 	lb_close_scope(p, lbDeferExit_Default, nullptr);
 	lb_close_scope(p, lbDeferExit_Default, nullptr);
 }
 }
 
 
-bool lb_switch_stmt_can_be_trivial_jump_table(AstSwitchStmt *ss, bool *default_found_) {
+gb_internal bool lb_switch_stmt_can_be_trivial_jump_table(AstSwitchStmt *ss, bool *default_found_) {
 	if (ss->tag == nullptr) {
 	if (ss->tag == nullptr) {
 		return false;
 		return false;
 	}
 	}
@@ -1138,7 +1128,7 @@ bool lb_switch_stmt_can_be_trivial_jump_table(AstSwitchStmt *ss, bool *default_f
 }
 }
 
 
 
 
-void lb_build_switch_stmt(lbProcedure *p, AstSwitchStmt *ss, Scope *scope) {
+gb_internal void lb_build_switch_stmt(lbProcedure *p, AstSwitchStmt *ss, Scope *scope) {
 	lb_open_scope(p, scope);
 	lb_open_scope(p, scope);
 
 
 	if (ss->init != nullptr) {
 	if (ss->init != nullptr) {
@@ -1300,7 +1290,7 @@ void lb_build_switch_stmt(lbProcedure *p, AstSwitchStmt *ss, Scope *scope) {
 	lb_close_scope(p, lbDeferExit_Default, done);
 	lb_close_scope(p, lbDeferExit_Default, done);
 }
 }
 
 
-void lb_store_type_case_implicit(lbProcedure *p, Ast *clause, lbValue value) {
+gb_internal void lb_store_type_case_implicit(lbProcedure *p, Ast *clause, lbValue value) {
 	Entity *e = implicit_entity_of_node(clause);
 	Entity *e = implicit_entity_of_node(clause);
 	GB_ASSERT(e != nullptr);
 	GB_ASSERT(e != nullptr);
 	if (e->flags & EntityFlag_Value) {
 	if (e->flags & EntityFlag_Value) {
@@ -1315,7 +1305,7 @@ void lb_store_type_case_implicit(lbProcedure *p, Ast *clause, lbValue value) {
 	}
 	}
 }
 }
 
 
-lbAddr lb_store_range_stmt_val(lbProcedure *p, Ast *stmt_val, lbValue value) {
+gb_internal lbAddr lb_store_range_stmt_val(lbProcedure *p, Ast *stmt_val, lbValue value) {
 	Entity *e = entity_of_node(stmt_val);
 	Entity *e = entity_of_node(stmt_val);
 	if (e == nullptr) {
 	if (e == nullptr) {
 		return {};
 		return {};
@@ -1335,7 +1325,7 @@ lbAddr lb_store_range_stmt_val(lbProcedure *p, Ast *stmt_val, lbValue value) {
 	return addr;
 	return addr;
 }
 }
 
 
-void lb_type_case_body(lbProcedure *p, Ast *label, Ast *clause, lbBlock *body, lbBlock *done) {
+gb_internal void lb_type_case_body(lbProcedure *p, Ast *label, Ast *clause, lbBlock *body, lbBlock *done) {
 	ast_node(cc, CaseClause, clause);
 	ast_node(cc, CaseClause, clause);
 
 
 	lb_push_target_list(p, label, done, nullptr, nullptr);
 	lb_push_target_list(p, label, done, nullptr, nullptr);
@@ -1346,7 +1336,7 @@ void lb_type_case_body(lbProcedure *p, Ast *label, Ast *clause, lbBlock *body, l
 	lb_emit_jump(p, done);
 	lb_emit_jump(p, done);
 }
 }
 
 
-void lb_build_type_switch_stmt(lbProcedure *p, AstTypeSwitchStmt *ss) {
+gb_internal void lb_build_type_switch_stmt(lbProcedure *p, AstTypeSwitchStmt *ss) {
 	lbModule *m = p->module;
 	lbModule *m = p->module;
 	lb_open_scope(p, ss->scope);
 	lb_open_scope(p, ss->scope);
 
 
@@ -1480,7 +1470,7 @@ void lb_build_type_switch_stmt(lbProcedure *p, AstTypeSwitchStmt *ss) {
 }
 }
 
 
 
 
-void lb_build_static_variables(lbProcedure *p, AstValueDecl *vd) {
+gb_internal void lb_build_static_variables(lbProcedure *p, AstValueDecl *vd) {
 	for_array(i, vd->names) {
 	for_array(i, vd->names) {
 		lbValue value = {};
 		lbValue value = {};
 		if (vd->values.count > 0) {
 		if (vd->values.count > 0) {
@@ -1543,7 +1533,7 @@ void lb_build_static_variables(lbProcedure *p, AstValueDecl *vd) {
 		lb_add_member(p->module, mangled_name, global_val);
 		lb_add_member(p->module, mangled_name, global_val);
 	}
 	}
 }
 }
-void lb_append_tuple_values(lbProcedure *p, Array<lbValue> *dst_values, lbValue src_value) {
+gb_internal void lb_append_tuple_values(lbProcedure *p, Array<lbValue> *dst_values, lbValue src_value) {
 	Type *t = src_value.type;
 	Type *t = src_value.type;
 	if (t->kind == Type_Tuple) {
 	if (t->kind == Type_Tuple) {
 		lbTupleFix *tf = map_get(&p->tuple_fix_map, src_value.value);
 		lbTupleFix *tf = map_get(&p->tuple_fix_map, src_value.value);
@@ -1563,7 +1553,7 @@ void lb_append_tuple_values(lbProcedure *p, Array<lbValue> *dst_values, lbValue
 }
 }
 
 
 
 
-void lb_build_assignment(lbProcedure *p, Array<lbAddr> &lvals, Slice<Ast *> const &values) {
+gb_internal void lb_build_assignment(lbProcedure *p, Array<lbAddr> &lvals, Slice<Ast *> const &values) {
 	if (values.count == 0) {
 	if (values.count == 0) {
 		return;
 		return;
 	}
 	}
@@ -1584,7 +1574,7 @@ void lb_build_assignment(lbProcedure *p, Array<lbAddr> &lvals, Slice<Ast *> cons
 	}
 	}
 }
 }
 
 
-void lb_build_return_stmt_internal(lbProcedure *p, lbValue res) {
+gb_internal void lb_build_return_stmt_internal(lbProcedure *p, lbValue res) {
 	lbFunctionType *ft = lb_get_function_type(p->module, p->type);
 	lbFunctionType *ft = lb_get_function_type(p->module, p->type);
 	bool return_by_pointer = ft->ret.kind == lbArg_Indirect;
 	bool return_by_pointer = ft->ret.kind == lbArg_Indirect;
 	bool split_returns = ft->multiple_return_original_type != nullptr;
 	bool split_returns = ft->multiple_return_original_type != nullptr;
@@ -1621,7 +1611,7 @@ void lb_build_return_stmt_internal(lbProcedure *p, lbValue res) {
 		LLVMBuildRet(p->builder, ret_val);
 		LLVMBuildRet(p->builder, ret_val);
 	}
 	}
 }
 }
-void lb_build_return_stmt(lbProcedure *p, Slice<Ast *> const &return_results) {
+gb_internal void lb_build_return_stmt(lbProcedure *p, Slice<Ast *> const &return_results) {
 	lb_ensure_abi_function_type(p->module, p);
 	lb_ensure_abi_function_type(p->module, p);
 
 
 	lbValue res = {};
 	lbValue res = {};
@@ -1765,7 +1755,7 @@ void lb_build_return_stmt(lbProcedure *p, Slice<Ast *> const &return_results) {
 	lb_build_return_stmt_internal(p, res);
 	lb_build_return_stmt_internal(p, res);
 }
 }
 
 
-void lb_build_if_stmt(lbProcedure *p, Ast *node) {
+gb_internal void lb_build_if_stmt(lbProcedure *p, Ast *node) {
 	ast_node(is, IfStmt, node);
 	ast_node(is, IfStmt, node);
 	lb_open_scope(p, is->scope); // Scope #1
 	lb_open_scope(p, is->scope); // Scope #1
 	defer (lb_close_scope(p, lbDeferExit_Default, nullptr));
 	defer (lb_close_scope(p, lbDeferExit_Default, nullptr));
@@ -1852,7 +1842,7 @@ void lb_build_if_stmt(lbProcedure *p, Ast *node) {
 	lb_start_block(p, done);
 	lb_start_block(p, done);
 }
 }
 
 
-void lb_build_for_stmt(lbProcedure *p, Ast *node) {
+gb_internal void lb_build_for_stmt(lbProcedure *p, Ast *node) {
 	ast_node(fs, ForStmt, node);
 	ast_node(fs, ForStmt, node);
 
 
 	lb_open_scope(p, fs->scope); // Open Scope here
 	lb_open_scope(p, fs->scope); // Open Scope here
@@ -1912,7 +1902,7 @@ void lb_build_for_stmt(lbProcedure *p, Ast *node) {
 	lb_close_scope(p, lbDeferExit_Default, nullptr);
 	lb_close_scope(p, lbDeferExit_Default, nullptr);
 }
 }
 
 
-void lb_build_assign_stmt_array(lbProcedure *p, TokenKind op, lbAddr const &lhs, lbValue const &value) {
+gb_internal void lb_build_assign_stmt_array(lbProcedure *p, TokenKind op, lbAddr const &lhs, lbValue const &value) {
 	GB_ASSERT(op != Token_Eq);
 	GB_ASSERT(op != Token_Eq);
 
 
 	Type *lhs_type = lb_addr_type(lhs);
 	Type *lhs_type = lb_addr_type(lhs);
@@ -2055,7 +2045,7 @@ void lb_build_assign_stmt_array(lbProcedure *p, TokenKind op, lbAddr const &lhs,
 		lb_loop_end(p, loop_data);
 		lb_loop_end(p, loop_data);
 	}
 	}
 }
 }
-void lb_build_assign_stmt(lbProcedure *p, AstAssignStmt *as) {
+gb_internal void lb_build_assign_stmt(lbProcedure *p, AstAssignStmt *as) {
 	if (as->op.kind == Token_Eq) {
 	if (as->op.kind == Token_Eq) {
 		auto lvals = array_make<lbAddr>(permanent_allocator(), 0, as->lhs.count);
 		auto lvals = array_make<lbAddr>(permanent_allocator(), 0, as->lhs.count);
 
 
@@ -2113,7 +2103,7 @@ void lb_build_assign_stmt(lbProcedure *p, AstAssignStmt *as) {
 }
 }
 
 
 
 
-void lb_build_stmt(lbProcedure *p, Ast *node) {
+gb_internal void lb_build_stmt(lbProcedure *p, Ast *node) {
 	Ast *prev_stmt = p->curr_stmt;
 	Ast *prev_stmt = p->curr_stmt;
 	defer (p->curr_stmt = prev_stmt);
 	defer (p->curr_stmt = prev_stmt);
 	p->curr_stmt = node;
 	p->curr_stmt = node;
@@ -2308,7 +2298,7 @@ void lb_build_stmt(lbProcedure *p, Ast *node) {
 
 
 
 
 
 
-void lb_build_defer_stmt(lbProcedure *p, lbDefer const &d) {
+gb_internal void lb_build_defer_stmt(lbProcedure *p, lbDefer const &d) {
 	if (p->curr_block == nullptr) {
 	if (p->curr_block == nullptr) {
 		return;
 		return;
 	}
 	}
@@ -2337,7 +2327,7 @@ void lb_build_defer_stmt(lbProcedure *p, lbDefer const &d) {
 	}
 	}
 }
 }
 
 
-void lb_emit_defer_stmts(lbProcedure *p, lbDeferExitKind kind, lbBlock *block) {
+gb_internal void lb_emit_defer_stmts(lbProcedure *p, lbDeferExitKind kind, lbBlock *block) {
 	isize count = p->defer_stmts.count;
 	isize count = p->defer_stmts.count;
 	isize i = count;
 	isize i = count;
 	while (i --> 0) {
 	while (i --> 0) {
@@ -2364,7 +2354,7 @@ void lb_emit_defer_stmts(lbProcedure *p, lbDeferExitKind kind, lbBlock *block) {
 	}
 	}
 }
 }
 
 
-void lb_add_defer_node(lbProcedure *p, isize scope_index, Ast *stmt) {
+gb_internal void lb_add_defer_node(lbProcedure *p, isize scope_index, Ast *stmt) {
 	Type *pt = base_type(p->type);
 	Type *pt = base_type(p->type);
 	GB_ASSERT(pt->kind == Type_Proc);
 	GB_ASSERT(pt->kind == Type_Proc);
 	if (pt->Proc.calling_convention == ProcCC_Odin) {
 	if (pt->Proc.calling_convention == ProcCC_Odin) {
@@ -2379,7 +2369,7 @@ void lb_add_defer_node(lbProcedure *p, isize scope_index, Ast *stmt) {
 	d->stmt = stmt;
 	d->stmt = stmt;
 }
 }
 
 
-void lb_add_defer_proc(lbProcedure *p, isize scope_index, lbValue deferred, Array<lbValue> const &result_as_args) {
+gb_internal void lb_add_defer_proc(lbProcedure *p, isize scope_index, lbValue deferred, Array<lbValue> const &result_as_args) {
 	Type *pt = base_type(p->type);
 	Type *pt = base_type(p->type);
 	GB_ASSERT(pt->kind == Type_Proc);
 	GB_ASSERT(pt->kind == Type_Proc);
 	if (pt->Proc.calling_convention == ProcCC_Odin) {
 	if (pt->Proc.calling_convention == ProcCC_Odin) {

+ 10 - 10
src/llvm_backend_type.cpp

@@ -1,4 +1,4 @@
-isize lb_type_info_index(CheckerInfo *info, Type *type, bool err_on_not_found=true) {
+gb_internal isize lb_type_info_index(CheckerInfo *info, Type *type, bool err_on_not_found=true) {
 	auto *set = &info->minimum_dependency_type_info_set;
 	auto *set = &info->minimum_dependency_type_info_set;
 	isize index = type_info_index(info, type, err_on_not_found);
 	isize index = type_info_index(info, type, err_on_not_found);
 	if (index >= 0) {
 	if (index >= 0) {
@@ -13,7 +13,7 @@ isize lb_type_info_index(CheckerInfo *info, Type *type, bool err_on_not_found=tr
 	return -1;
 	return -1;
 }
 }
 
 
-lbValue lb_typeid(lbModule *m, Type *type) {
+gb_internal lbValue lb_typeid(lbModule *m, Type *type) {
 	GB_ASSERT(!build_context.disallow_rtti);
 	GB_ASSERT(!build_context.disallow_rtti);
 
 
 	type = default_type(type);
 	type = default_type(type);
@@ -90,7 +90,7 @@ lbValue lb_typeid(lbModule *m, Type *type) {
 	return res;
 	return res;
 }
 }
 
 
-lbValue lb_type_info(lbModule *m, Type *type) {
+gb_internal lbValue lb_type_info(lbModule *m, Type *type) {
 	GB_ASSERT(!build_context.disallow_rtti);
 	GB_ASSERT(!build_context.disallow_rtti);
 
 
 	type = default_type(type);
 	type = default_type(type);
@@ -102,36 +102,36 @@ lbValue lb_type_info(lbModule *m, Type *type) {
 	return lb_emit_array_epi(m, data, index);
 	return lb_emit_array_epi(m, data, index);
 }
 }
 
 
-LLVMTypeRef lb_get_procedure_raw_type(lbModule *m, Type *type) {
+gb_internal LLVMTypeRef lb_get_procedure_raw_type(lbModule *m, Type *type) {
 	return lb_type_internal_for_procedures_raw(m, type);
 	return lb_type_internal_for_procedures_raw(m, type);
 }
 }
 
 
 
 
-lbValue lb_type_info_member_types_offset(lbProcedure *p, isize count) {
+gb_internal lbValue lb_type_info_member_types_offset(lbProcedure *p, isize count) {
 	GB_ASSERT(p->module == &p->module->gen->default_module);
 	GB_ASSERT(p->module == &p->module->gen->default_module);
 	lbValue offset = lb_emit_array_epi(p, lb_global_type_info_member_types.addr, lb_global_type_info_member_types_index);
 	lbValue offset = lb_emit_array_epi(p, lb_global_type_info_member_types.addr, lb_global_type_info_member_types_index);
 	lb_global_type_info_member_types_index += cast(i32)count;
 	lb_global_type_info_member_types_index += cast(i32)count;
 	return offset;
 	return offset;
 }
 }
-lbValue lb_type_info_member_names_offset(lbProcedure *p, isize count) {
+gb_internal lbValue lb_type_info_member_names_offset(lbProcedure *p, isize count) {
 	GB_ASSERT(p->module == &p->module->gen->default_module);
 	GB_ASSERT(p->module == &p->module->gen->default_module);
 	lbValue offset = lb_emit_array_epi(p, lb_global_type_info_member_names.addr, lb_global_type_info_member_names_index);
 	lbValue offset = lb_emit_array_epi(p, lb_global_type_info_member_names.addr, lb_global_type_info_member_names_index);
 	lb_global_type_info_member_names_index += cast(i32)count;
 	lb_global_type_info_member_names_index += cast(i32)count;
 	return offset;
 	return offset;
 }
 }
-lbValue lb_type_info_member_offsets_offset(lbProcedure *p, isize count) {
+gb_internal lbValue lb_type_info_member_offsets_offset(lbProcedure *p, isize count) {
 	GB_ASSERT(p->module == &p->module->gen->default_module);
 	GB_ASSERT(p->module == &p->module->gen->default_module);
 	lbValue offset = lb_emit_array_epi(p, lb_global_type_info_member_offsets.addr, lb_global_type_info_member_offsets_index);
 	lbValue offset = lb_emit_array_epi(p, lb_global_type_info_member_offsets.addr, lb_global_type_info_member_offsets_index);
 	lb_global_type_info_member_offsets_index += cast(i32)count;
 	lb_global_type_info_member_offsets_index += cast(i32)count;
 	return offset;
 	return offset;
 }
 }
-lbValue lb_type_info_member_usings_offset(lbProcedure *p, isize count) {
+gb_internal lbValue lb_type_info_member_usings_offset(lbProcedure *p, isize count) {
 	GB_ASSERT(p->module == &p->module->gen->default_module);
 	GB_ASSERT(p->module == &p->module->gen->default_module);
 	lbValue offset = lb_emit_array_epi(p, lb_global_type_info_member_usings.addr, lb_global_type_info_member_usings_index);
 	lbValue offset = lb_emit_array_epi(p, lb_global_type_info_member_usings.addr, lb_global_type_info_member_usings_index);
 	lb_global_type_info_member_usings_index += cast(i32)count;
 	lb_global_type_info_member_usings_index += cast(i32)count;
 	return offset;
 	return offset;
 }
 }
-lbValue lb_type_info_member_tags_offset(lbProcedure *p, isize count) {
+gb_internal lbValue lb_type_info_member_tags_offset(lbProcedure *p, isize count) {
 	GB_ASSERT(p->module == &p->module->gen->default_module);
 	GB_ASSERT(p->module == &p->module->gen->default_module);
 	lbValue offset = lb_emit_array_epi(p, lb_global_type_info_member_tags.addr, lb_global_type_info_member_tags_index);
 	lbValue offset = lb_emit_array_epi(p, lb_global_type_info_member_tags.addr, lb_global_type_info_member_tags_index);
 	lb_global_type_info_member_tags_index += cast(i32)count;
 	lb_global_type_info_member_tags_index += cast(i32)count;
@@ -139,7 +139,7 @@ lbValue lb_type_info_member_tags_offset(lbProcedure *p, isize count) {
 }
 }
 
 
 
 
-void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info data
+gb_internal void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info data
 	if (build_context.disallow_rtti) {
 	if (build_context.disallow_rtti) {
 		return;
 		return;
 	}
 	}

+ 95 - 107
src/llvm_backend_utility.cpp

@@ -1,6 +1,6 @@
-lbValue lb_lookup_runtime_procedure(lbModule *m, String const &name);
+gb_internal lbValue lb_lookup_runtime_procedure(lbModule *m, String const &name);
 
 
-bool lb_is_type_aggregate(Type *t) {
+gb_internal bool lb_is_type_aggregate(Type *t) {
 	t = base_type(t);
 	t = base_type(t);
 	switch (t->kind) {
 	switch (t->kind) {
 	case Type_Basic:
 	case Type_Basic:
@@ -39,7 +39,7 @@ bool lb_is_type_aggregate(Type *t) {
 	return false;
 	return false;
 }
 }
 
 
-void lb_emit_unreachable(lbProcedure *p) {
+gb_internal void lb_emit_unreachable(lbProcedure *p) {
 	LLVMValueRef instr = LLVMGetLastInstruction(p->curr_block->block);
 	LLVMValueRef instr = LLVMGetLastInstruction(p->curr_block->block);
 	if (instr == nullptr || !lb_is_instr_terminating(instr)) {
 	if (instr == nullptr || !lb_is_instr_terminating(instr)) {
 		lb_call_intrinsic(p, "llvm.trap", nullptr, 0, nullptr, 0);
 		lb_call_intrinsic(p, "llvm.trap", nullptr, 0, nullptr, 0);
@@ -47,7 +47,7 @@ void lb_emit_unreachable(lbProcedure *p) {
 	}
 	}
 }
 }
 
 
-lbValue lb_correct_endianness(lbProcedure *p, lbValue value) {
+gb_internal lbValue lb_correct_endianness(lbProcedure *p, lbValue value) {
 	Type *src = core_type(value.type);
 	Type *src = core_type(value.type);
 	GB_ASSERT(is_type_integer(src) || is_type_float(src));
 	GB_ASSERT(is_type_integer(src) || is_type_float(src));
 	if (is_type_different_to_arch_endianness(src)) {
 	if (is_type_different_to_arch_endianness(src)) {
@@ -57,7 +57,7 @@ lbValue lb_correct_endianness(lbProcedure *p, lbValue value) {
 	return value;
 	return value;
 }
 }
 
 
-LLVMValueRef lb_mem_zero_ptr_internal(lbProcedure *p, LLVMValueRef ptr, LLVMValueRef len, unsigned alignment, bool is_volatile) {
+gb_internal LLVMValueRef lb_mem_zero_ptr_internal(lbProcedure *p, LLVMValueRef ptr, LLVMValueRef len, unsigned alignment, bool is_volatile) {
 	bool is_inlinable = false;
 	bool is_inlinable = false;
 
 
 	i64 const_len = 0;
 	i64 const_len = 0;
@@ -103,7 +103,7 @@ LLVMValueRef lb_mem_zero_ptr_internal(lbProcedure *p, LLVMValueRef ptr, LLVMValu
 
 
 }
 }
 
 
-void lb_mem_zero_ptr(lbProcedure *p, LLVMValueRef ptr, Type *type, unsigned alignment) {
+gb_internal void lb_mem_zero_ptr(lbProcedure *p, LLVMValueRef ptr, Type *type, unsigned alignment) {
 	LLVMTypeRef llvm_type = lb_type(p->module, type);
 	LLVMTypeRef llvm_type = lb_type(p->module, type);
 
 
 	LLVMTypeKind kind = LLVMGetTypeKind(llvm_type);
 	LLVMTypeKind kind = LLVMGetTypeKind(llvm_type);
@@ -123,7 +123,7 @@ void lb_mem_zero_ptr(lbProcedure *p, LLVMValueRef ptr, Type *type, unsigned alig
 	}
 	}
 }
 }
 
 
-lbValue lb_emit_select(lbProcedure *p, lbValue cond, lbValue x, lbValue y) {
+gb_internal lbValue lb_emit_select(lbProcedure *p, lbValue cond, lbValue x, lbValue y) {
 	cond = lb_emit_conv(p, cond, t_llvm_bool);
 	cond = lb_emit_conv(p, cond, t_llvm_bool);
 	lbValue res = {};
 	lbValue res = {};
 	res.value = LLVMBuildSelect(p->builder, cond.value, x.value, y.value, "");
 	res.value = LLVMBuildSelect(p->builder, cond.value, x.value, y.value, "");
@@ -131,19 +131,19 @@ lbValue lb_emit_select(lbProcedure *p, lbValue cond, lbValue x, lbValue y) {
 	return res;
 	return res;
 }
 }
 
 
-lbValue lb_emit_min(lbProcedure *p, Type *t, lbValue x, lbValue y) {
+gb_internal lbValue lb_emit_min(lbProcedure *p, Type *t, lbValue x, lbValue y) {
 	x = lb_emit_conv(p, x, t);
 	x = lb_emit_conv(p, x, t);
 	y = lb_emit_conv(p, y, t);
 	y = lb_emit_conv(p, y, t);
 	return lb_emit_select(p, lb_emit_comp(p, Token_Lt, x, y), x, y);
 	return lb_emit_select(p, lb_emit_comp(p, Token_Lt, x, y), x, y);
 }
 }
-lbValue lb_emit_max(lbProcedure *p, Type *t, lbValue x, lbValue y) {
+gb_internal lbValue lb_emit_max(lbProcedure *p, Type *t, lbValue x, lbValue y) {
 	x = lb_emit_conv(p, x, t);
 	x = lb_emit_conv(p, x, t);
 	y = lb_emit_conv(p, y, t);
 	y = lb_emit_conv(p, y, t);
 	return lb_emit_select(p, lb_emit_comp(p, Token_Gt, x, y), x, y);
 	return lb_emit_select(p, lb_emit_comp(p, Token_Gt, x, y), x, y);
 }
 }
 
 
 
 
-lbValue lb_emit_clamp(lbProcedure *p, Type *t, lbValue x, lbValue min, lbValue max) {
+gb_internal lbValue lb_emit_clamp(lbProcedure *p, Type *t, lbValue x, lbValue min, lbValue max) {
 	lbValue z = {};
 	lbValue z = {};
 	z = lb_emit_max(p, t, x, min);
 	z = lb_emit_max(p, t, x, min);
 	z = lb_emit_min(p, t, z, max);
 	z = lb_emit_min(p, t, z, max);
@@ -152,7 +152,7 @@ lbValue lb_emit_clamp(lbProcedure *p, Type *t, lbValue x, lbValue min, lbValue m
 
 
 
 
 
 
-lbValue lb_emit_string(lbProcedure *p, lbValue str_elem, lbValue str_len) {
+gb_internal lbValue lb_emit_string(lbProcedure *p, lbValue str_elem, lbValue str_len) {
 	if (false && lb_is_const(str_elem) && lb_is_const(str_len)) {
 	if (false && lb_is_const(str_elem) && lb_is_const(str_len)) {
 		LLVMValueRef values[2] = {
 		LLVMValueRef values[2] = {
 			str_elem.value,
 			str_elem.value,
@@ -171,7 +171,7 @@ lbValue lb_emit_string(lbProcedure *p, lbValue str_elem, lbValue str_len) {
 }
 }
 
 
 
 
-lbValue lb_emit_transmute(lbProcedure *p, lbValue value, Type *t) {
+gb_internal lbValue lb_emit_transmute(lbProcedure *p, lbValue value, Type *t) {
 	Type *src_type = value.type;
 	Type *src_type = value.type;
 	if (are_types_identical(t, src_type)) {
 	if (are_types_identical(t, src_type)) {
 		return value;
 		return value;
@@ -259,7 +259,7 @@ lbValue lb_emit_transmute(lbProcedure *p, lbValue value, Type *t) {
 	return res;
 	return res;
 }
 }
 
 
-lbValue lb_copy_value_to_ptr(lbProcedure *p, lbValue val, Type *new_type, i64 alignment) {
+gb_internal lbValue lb_copy_value_to_ptr(lbProcedure *p, lbValue val, Type *new_type, i64 alignment) {
 	i64 type_alignment = type_align_of(new_type);
 	i64 type_alignment = type_align_of(new_type);
 	if (alignment < type_alignment) {
 	if (alignment < type_alignment) {
 		alignment = type_alignment;
 		alignment = type_alignment;
@@ -274,7 +274,7 @@ lbValue lb_copy_value_to_ptr(lbProcedure *p, lbValue val, Type *new_type, i64 al
 }
 }
 
 
 
 
-lbValue lb_soa_zip(lbProcedure *p, AstCallExpr *ce, TypeAndValue const &tv) {
+gb_internal lbValue lb_soa_zip(lbProcedure *p, AstCallExpr *ce, TypeAndValue const &tv) {
 	GB_ASSERT(ce->args.count > 0);
 	GB_ASSERT(ce->args.count > 0);
 
 
 	auto slices = slice_make<lbValue>(temporary_allocator(), ce->args.count);
 	auto slices = slice_make<lbValue>(temporary_allocator(), ce->args.count);
@@ -305,7 +305,7 @@ lbValue lb_soa_zip(lbProcedure *p, AstCallExpr *ce, TypeAndValue const &tv) {
 	return lb_addr_load(p, res);
 	return lb_addr_load(p, res);
 }
 }
 
 
-lbValue lb_soa_unzip(lbProcedure *p, AstCallExpr *ce, TypeAndValue const &tv) {
+gb_internal lbValue lb_soa_unzip(lbProcedure *p, AstCallExpr *ce, TypeAndValue const &tv) {
 	GB_ASSERT(ce->args.count == 1);
 	GB_ASSERT(ce->args.count == 1);
 
 
 	lbValue arg = lb_build_expr(p, ce->args[0]);
 	lbValue arg = lb_build_expr(p, ce->args[0]);
@@ -331,7 +331,7 @@ lbValue lb_soa_unzip(lbProcedure *p, AstCallExpr *ce, TypeAndValue const &tv) {
 	return lb_addr_load(p, res);
 	return lb_addr_load(p, res);
 }
 }
 
 
-void lb_emit_try_lhs_rhs(lbProcedure *p, Ast *arg, TypeAndValue const &tv, lbValue *lhs_, lbValue *rhs_) {
+gb_internal void lb_emit_try_lhs_rhs(lbProcedure *p, Ast *arg, TypeAndValue const &tv, lbValue *lhs_, lbValue *rhs_) {
 	lbValue lhs = {};
 	lbValue lhs = {};
 	lbValue rhs = {};
 	lbValue rhs = {};
 
 
@@ -360,7 +360,7 @@ void lb_emit_try_lhs_rhs(lbProcedure *p, Ast *arg, TypeAndValue const &tv, lbVal
 }
 }
 
 
 
 
-lbValue lb_emit_try_has_value(lbProcedure *p, lbValue rhs) {
+gb_internal lbValue lb_emit_try_has_value(lbProcedure *p, lbValue rhs) {
 	lbValue has_value = {};
 	lbValue has_value = {};
 	if (is_type_boolean(rhs.type)) {
 	if (is_type_boolean(rhs.type)) {
 		has_value = rhs;
 		has_value = rhs;
@@ -373,7 +373,7 @@ lbValue lb_emit_try_has_value(lbProcedure *p, lbValue rhs) {
 }
 }
 
 
 
 
-lbValue lb_emit_or_else(lbProcedure *p, Ast *arg, Ast *else_expr, TypeAndValue const &tv) {
+gb_internal lbValue lb_emit_or_else(lbProcedure *p, Ast *arg, Ast *else_expr, TypeAndValue const &tv) {
 	if (arg->state_flags & StateFlag_DirectiveWasFalse) {
 	if (arg->state_flags & StateFlag_DirectiveWasFalse) {
 		return lb_build_expr(p, else_expr);
 		return lb_build_expr(p, else_expr);
 	}
 	}
@@ -435,10 +435,10 @@ lbValue lb_emit_or_else(lbProcedure *p, Ast *arg, Ast *else_expr, TypeAndValue c
 	}
 	}
 }
 }
 
 
-void lb_build_return_stmt(lbProcedure *p, Slice<Ast *> const &return_results);
-void lb_build_return_stmt_internal(lbProcedure *p, lbValue res);
+gb_internal void lb_build_return_stmt(lbProcedure *p, Slice<Ast *> const &return_results);
+gb_internal void lb_build_return_stmt_internal(lbProcedure *p, lbValue res);
 
 
-lbValue lb_emit_or_return(lbProcedure *p, Ast *arg, TypeAndValue const &tv) {
+gb_internal lbValue lb_emit_or_return(lbProcedure *p, Ast *arg, TypeAndValue const &tv) {
 	lbValue lhs = {};
 	lbValue lhs = {};
 	lbValue rhs = {};
 	lbValue rhs = {};
 	lb_emit_try_lhs_rhs(p, arg, tv, &lhs, &rhs);
 	lb_emit_try_lhs_rhs(p, arg, tv, &lhs, &rhs);
@@ -479,7 +479,7 @@ lbValue lb_emit_or_return(lbProcedure *p, Ast *arg, TypeAndValue const &tv) {
 }
 }
 
 
 
 
-void lb_emit_increment(lbProcedure *p, lbValue addr) {
+gb_internal void lb_emit_increment(lbProcedure *p, lbValue addr) {
 	GB_ASSERT(is_type_pointer(addr.type));
 	GB_ASSERT(is_type_pointer(addr.type));
 	Type *type = type_deref(addr.type);
 	Type *type = type_deref(addr.type);
 	lbValue v_one = lb_const_value(p->module, type, exact_value_i64(1));
 	lbValue v_one = lb_const_value(p->module, type, exact_value_i64(1));
@@ -487,7 +487,7 @@ void lb_emit_increment(lbProcedure *p, lbValue addr) {
 
 
 }
 }
 
 
-lbValue lb_emit_byte_swap(lbProcedure *p, lbValue value, Type *end_type) {
+gb_internal lbValue lb_emit_byte_swap(lbProcedure *p, lbValue value, Type *end_type) {
 	GB_ASSERT(type_size_of(value.type) == type_size_of(end_type));
 	GB_ASSERT(type_size_of(value.type) == type_size_of(end_type));
 
 
 	if (type_size_of(value.type) < 2) {
 	if (type_size_of(value.type) < 2) {
@@ -526,7 +526,7 @@ lbValue lb_emit_byte_swap(lbProcedure *p, lbValue value, Type *end_type) {
 
 
 
 
 
 
-lbValue lb_emit_count_ones(lbProcedure *p, lbValue x, Type *type) {
+gb_internal lbValue lb_emit_count_ones(lbProcedure *p, lbValue x, Type *type) {
 	x = lb_emit_conv(p, x, type);
 	x = lb_emit_conv(p, x, type);
 
 
 	char const *name = "llvm.ctpop";
 	char const *name = "llvm.ctpop";
@@ -539,7 +539,7 @@ lbValue lb_emit_count_ones(lbProcedure *p, lbValue x, Type *type) {
 	return res;
 	return res;
 }
 }
 
 
-lbValue lb_emit_count_zeros(lbProcedure *p, lbValue x, Type *type) {
+gb_internal lbValue lb_emit_count_zeros(lbProcedure *p, lbValue x, Type *type) {
 	Type *elem = base_array_type(type);
 	Type *elem = base_array_type(type);
 	i64 sz = 8*type_size_of(elem);
 	i64 sz = 8*type_size_of(elem);
 	lbValue size = lb_const_int(p->module, elem, cast(u64)sz);
 	lbValue size = lb_const_int(p->module, elem, cast(u64)sz);
@@ -550,7 +550,7 @@ lbValue lb_emit_count_zeros(lbProcedure *p, lbValue x, Type *type) {
 
 
 
 
 
 
-lbValue lb_emit_count_trailing_zeros(lbProcedure *p, lbValue x, Type *type) {
+gb_internal lbValue lb_emit_count_trailing_zeros(lbProcedure *p, lbValue x, Type *type) {
 	x = lb_emit_conv(p, x, type);
 	x = lb_emit_conv(p, x, type);
 
 
 	char const *name = "llvm.cttz";
 	char const *name = "llvm.cttz";
@@ -566,7 +566,7 @@ lbValue lb_emit_count_trailing_zeros(lbProcedure *p, lbValue x, Type *type) {
 	return res;
 	return res;
 }
 }
 
 
-lbValue lb_emit_count_leading_zeros(lbProcedure *p, lbValue x, Type *type) {
+gb_internal lbValue lb_emit_count_leading_zeros(lbProcedure *p, lbValue x, Type *type) {
 	x = lb_emit_conv(p, x, type);
 	x = lb_emit_conv(p, x, type);
 
 
 	char const *name = "llvm.ctlz";
 	char const *name = "llvm.ctlz";
@@ -584,7 +584,7 @@ lbValue lb_emit_count_leading_zeros(lbProcedure *p, lbValue x, Type *type) {
 
 
 
 
 
 
-lbValue lb_emit_reverse_bits(lbProcedure *p, lbValue x, Type *type) {
+gb_internal lbValue lb_emit_reverse_bits(lbProcedure *p, lbValue x, Type *type) {
 	x = lb_emit_conv(p, x, type);
 	x = lb_emit_conv(p, x, type);
 
 
 	char const *name = "llvm.bitreverse";
 	char const *name = "llvm.bitreverse";
@@ -599,15 +599,7 @@ lbValue lb_emit_reverse_bits(lbProcedure *p, lbValue x, Type *type) {
 }
 }
 
 
 
 
-lbValue lb_emit_bit_set_card(lbProcedure *p, lbValue x) {
-	GB_ASSERT(is_type_bit_set(x.type));
-	Type *underlying = bit_set_to_int(x.type);
-	lbValue card = lb_emit_count_ones(p, x, underlying);
-	return lb_emit_conv(p, card, t_int);
-}
-
-
-lbValue lb_emit_union_cast_only_ok_check(lbProcedure *p, lbValue value, Type *type, TokenPos pos) {
+gb_internal lbValue lb_emit_union_cast_only_ok_check(lbProcedure *p, lbValue value, Type *type, TokenPos pos) {
 	GB_ASSERT(is_type_tuple(type));
 	GB_ASSERT(is_type_tuple(type));
 	lbModule *m = p->module;
 	lbModule *m = p->module;
 
 
@@ -654,7 +646,7 @@ lbValue lb_emit_union_cast_only_ok_check(lbProcedure *p, lbValue value, Type *ty
 	return lb_addr_load(p, v);
 	return lb_addr_load(p, v);
 }
 }
 
 
-lbValue lb_emit_union_cast(lbProcedure *p, lbValue value, Type *type, TokenPos pos) {
+gb_internal lbValue lb_emit_union_cast(lbProcedure *p, lbValue value, Type *type, TokenPos pos) {
 	lbModule *m = p->module;
 	lbModule *m = p->module;
 
 
 	Type *src_type = value.type;
 	Type *src_type = value.type;
@@ -753,7 +745,7 @@ lbValue lb_emit_union_cast(lbProcedure *p, lbValue value, Type *type, TokenPos p
 	return lb_addr_load(p, v);
 	return lb_addr_load(p, v);
 }
 }
 
 
-lbAddr lb_emit_any_cast_addr(lbProcedure *p, lbValue value, Type *type, TokenPos pos) {
+gb_internal lbAddr lb_emit_any_cast_addr(lbProcedure *p, lbValue value, Type *type, TokenPos pos) {
 	lbModule *m = p->module;
 	lbModule *m = p->module;
 
 
 	Type *src_type = value.type;
 	Type *src_type = value.type;
@@ -826,13 +818,13 @@ lbAddr lb_emit_any_cast_addr(lbProcedure *p, lbValue value, Type *type, TokenPos
 	}
 	}
 	return v;
 	return v;
 }
 }
-lbValue lb_emit_any_cast(lbProcedure *p, lbValue value, Type *type, TokenPos pos) {
+gb_internal lbValue lb_emit_any_cast(lbProcedure *p, lbValue value, Type *type, TokenPos pos) {
 	return lb_addr_load(p, lb_emit_any_cast_addr(p, value, type, pos));
 	return lb_addr_load(p, lb_emit_any_cast_addr(p, value, type, pos));
 }
 }
 
 
 
 
 
 
-lbAddr lb_find_or_generate_context_ptr(lbProcedure *p) {
+gb_internal lbAddr lb_find_or_generate_context_ptr(lbProcedure *p) {
 	if (p->context_stack.count > 0) {
 	if (p->context_stack.count > 0) {
 		return p->context_stack[p->context_stack.count-1].ctx;
 		return p->context_stack[p->context_stack.count-1].ctx;
 	}
 	}
@@ -850,7 +842,7 @@ lbAddr lb_find_or_generate_context_ptr(lbProcedure *p) {
 	return c;
 	return c;
 }
 }
 
 
-lbValue lb_address_from_load_or_generate_local(lbProcedure *p, lbValue value) {
+gb_internal lbValue lb_address_from_load_or_generate_local(lbProcedure *p, lbValue value) {
 	if (LLVMIsALoadInst(value.value)) {
 	if (LLVMIsALoadInst(value.value)) {
 		lbValue res = {};
 		lbValue res = {};
 		res.value = LLVMGetOperand(value.value, 0);
 		res.value = LLVMGetOperand(value.value, 0);
@@ -864,7 +856,7 @@ lbValue lb_address_from_load_or_generate_local(lbProcedure *p, lbValue value) {
 	lb_addr_store(p, res, value);
 	lb_addr_store(p, res, value);
 	return res.addr;
 	return res.addr;
 }
 }
-lbValue lb_address_from_load(lbProcedure *p, lbValue value) {
+gb_internal lbValue lb_address_from_load(lbProcedure *p, lbValue value) {
 	if (LLVMIsALoadInst(value.value)) {
 	if (LLVMIsALoadInst(value.value)) {
 		lbValue res = {};
 		lbValue res = {};
 		res.value = LLVMGetOperand(value.value, 0);
 		res.value = LLVMGetOperand(value.value, 0);
@@ -877,7 +869,7 @@ lbValue lb_address_from_load(lbProcedure *p, lbValue value) {
 }
 }
 
 
 
 
-lbStructFieldRemapping lb_get_struct_remapping(lbModule *m, Type *t) {
+gb_internal lbStructFieldRemapping lb_get_struct_remapping(lbModule *m, Type *t) {
 	t = base_type(t);
 	t = base_type(t);
 	LLVMTypeRef struct_type = lb_type(m, t);
 	LLVMTypeRef struct_type = lb_type(m, t);
 	auto *field_remapping = map_get(&m->struct_field_remapping, cast(void *)struct_type);
 	auto *field_remapping = map_get(&m->struct_field_remapping, cast(void *)struct_type);
@@ -888,7 +880,7 @@ lbStructFieldRemapping lb_get_struct_remapping(lbModule *m, Type *t) {
 	return *field_remapping;
 	return *field_remapping;
 }
 }
 
 
-i32 lb_convert_struct_index(lbModule *m, Type *t, i32 index) {
+gb_internal i32 lb_convert_struct_index(lbModule *m, Type *t, i32 index) {
 	if (t->kind == Type_Struct) {
 	if (t->kind == Type_Struct) {
 		auto field_remapping = lb_get_struct_remapping(m, t);
 		auto field_remapping = lb_get_struct_remapping(m, t);
 		index = field_remapping[index];
 		index = field_remapping[index];
@@ -896,7 +888,7 @@ i32 lb_convert_struct_index(lbModule *m, Type *t, i32 index) {
 	return index;
 	return index;
 }
 }
 
 
-LLVMTypeRef lb_type_padding_filler(lbModule *m, i64 padding, i64 padding_align) {
+gb_internal LLVMTypeRef lb_type_padding_filler(lbModule *m, i64 padding, i64 padding_align) {
 	// NOTE(bill): limit to `[N x u64]` to prevent ABI issues
 	// NOTE(bill): limit to `[N x u64]` to prevent ABI issues
 	padding_align = gb_clamp(padding_align, 1, 8);
 	padding_align = gb_clamp(padding_align, 1, 8);
 	if (padding % padding_align == 0) {
 	if (padding % padding_align == 0) {
@@ -921,7 +913,7 @@ LLVMTypeRef lb_type_padding_filler(lbModule *m, i64 padding, i64 padding_align)
 }
 }
 
 
 
 
-char const *llvm_type_kinds[] = {
+gb_global char const *llvm_type_kinds[] = {
 	"LLVMVoidTypeKind",
 	"LLVMVoidTypeKind",
 	"LLVMHalfTypeKind",
 	"LLVMHalfTypeKind",
 	"LLVMFloatTypeKind",
 	"LLVMFloatTypeKind",
@@ -973,7 +965,7 @@ gb_internal lbValue lb_emit_struct_ep_internal(lbProcedure *p, lbValue s, i32 in
 	}
 	}
 }
 }
 
 
-lbValue lb_emit_tuple_ep(lbProcedure *p, lbValue ptr, i32 index) {
+gb_internal lbValue lb_emit_tuple_ep(lbProcedure *p, lbValue ptr, i32 index) {
 	Type *t = type_deref(ptr.type);
 	Type *t = type_deref(ptr.type);
 	GB_ASSERT(is_type_tuple(t));
 	GB_ASSERT(is_type_tuple(t));
 	Type *result_type = t->Tuple.variables[index]->type;
 	Type *result_type = t->Tuple.variables[index]->type;
@@ -991,7 +983,7 @@ lbValue lb_emit_tuple_ep(lbProcedure *p, lbValue ptr, i32 index) {
 }
 }
 
 
 
 
-lbValue lb_emit_struct_ep(lbProcedure *p, lbValue s, i32 index) {
+gb_internal lbValue lb_emit_struct_ep(lbProcedure *p, lbValue s, i32 index) {
 	GB_ASSERT(is_type_pointer(s.type));
 	GB_ASSERT(is_type_pointer(s.type));
 	Type *t = base_type(type_deref(s.type));
 	Type *t = base_type(type_deref(s.type));
 	Type *result_type = nullptr;
 	Type *result_type = nullptr;
@@ -1074,7 +1066,7 @@ lbValue lb_emit_struct_ep(lbProcedure *p, lbValue s, i32 index) {
 	return lb_emit_struct_ep_internal(p, s, index, result_type);
 	return lb_emit_struct_ep_internal(p, s, index, result_type);
 }
 }
 
 
-lbValue lb_emit_tuple_ev(lbProcedure *p, lbValue value, i32 index) {
+gb_internal lbValue lb_emit_tuple_ev(lbProcedure *p, lbValue value, i32 index) {
 	Type *t = value.type;
 	Type *t = value.type;
 	GB_ASSERT(is_type_tuple(t));
 	GB_ASSERT(is_type_tuple(t));
 	Type *result_type = t->Tuple.variables[index]->type;
 	Type *result_type = t->Tuple.variables[index]->type;
@@ -1104,7 +1096,7 @@ lbValue lb_emit_tuple_ev(lbProcedure *p, lbValue value, i32 index) {
 	return res;
 	return res;
 }
 }
 
 
-lbValue lb_emit_struct_ev(lbProcedure *p, lbValue s, i32 index) {
+gb_internal lbValue lb_emit_struct_ev(lbProcedure *p, lbValue s, i32 index) {
 	Type *t = base_type(s.type);
 	Type *t = base_type(s.type);
 	if (is_type_tuple(t)) {
 	if (is_type_tuple(t)) {
 		return lb_emit_tuple_ev(p, s, index);
 		return lb_emit_tuple_ev(p, s, index);
@@ -1223,7 +1215,7 @@ lbValue lb_emit_struct_ev(lbProcedure *p, lbValue s, i32 index) {
 	return res;
 	return res;
 }
 }
 
 
-lbValue lb_emit_deep_field_gep(lbProcedure *p, lbValue e, Selection sel) {
+gb_internal lbValue lb_emit_deep_field_gep(lbProcedure *p, lbValue e, Selection sel) {
 	GB_ASSERT(sel.index.count > 0);
 	GB_ASSERT(sel.index.count > 0);
 	Type *type = type_deref(e.type);
 	Type *type = type_deref(e.type);
 
 
@@ -1311,14 +1303,14 @@ lbValue lb_emit_deep_field_gep(lbProcedure *p, lbValue e, Selection sel) {
 }
 }
 
 
 
 
-lbValue lb_emit_deep_field_ev(lbProcedure *p, lbValue e, Selection sel) {
+gb_internal lbValue lb_emit_deep_field_ev(lbProcedure *p, lbValue e, Selection sel) {
 	lbValue ptr = lb_address_from_load_or_generate_local(p, e);
 	lbValue ptr = lb_address_from_load_or_generate_local(p, e);
 	lbValue res = lb_emit_deep_field_gep(p, ptr, sel);
 	lbValue res = lb_emit_deep_field_gep(p, ptr, sel);
 	return lb_emit_load(p, res);
 	return lb_emit_load(p, res);
 }
 }
 
 
 
 
-lbValue lb_emit_array_ep(lbProcedure *p, lbValue s, lbValue index) {
+gb_internal lbValue lb_emit_array_ep(lbProcedure *p, lbValue s, lbValue index) {
 	Type *t = s.type;
 	Type *t = s.type;
 	GB_ASSERT_MSG(is_type_pointer(t), "%s", type_to_string(t));
 	GB_ASSERT_MSG(is_type_pointer(t), "%s", type_to_string(t));
 	Type *st = base_type(type_deref(t));
 	Type *st = base_type(type_deref(t));
@@ -1341,7 +1333,7 @@ lbValue lb_emit_array_ep(lbProcedure *p, lbValue s, lbValue index) {
 	return res;
 	return res;
 }
 }
 
 
-lbValue lb_emit_array_epi(lbProcedure *p, lbValue s, isize index) {
+gb_internal lbValue lb_emit_array_epi(lbProcedure *p, lbValue s, isize index) {
 	Type *t = s.type;
 	Type *t = s.type;
 	GB_ASSERT(is_type_pointer(t));
 	GB_ASSERT(is_type_pointer(t));
 	Type *st = base_type(type_deref(t));
 	Type *st = base_type(type_deref(t));
@@ -1349,7 +1341,7 @@ lbValue lb_emit_array_epi(lbProcedure *p, lbValue s, isize index) {
 	GB_ASSERT(0 <= index);
 	GB_ASSERT(0 <= index);
 	return lb_emit_epi(p, s, index);
 	return lb_emit_epi(p, s, index);
 }
 }
-lbValue lb_emit_array_epi(lbModule *m, lbValue s, isize index) {
+gb_internal lbValue lb_emit_array_epi(lbModule *m, lbValue s, isize index) {
 	Type *t = s.type;
 	Type *t = s.type;
 	GB_ASSERT(is_type_pointer(t));
 	GB_ASSERT(is_type_pointer(t));
 	Type *st = base_type(type_deref(t));
 	Type *st = base_type(type_deref(t));
@@ -1358,7 +1350,7 @@ lbValue lb_emit_array_epi(lbModule *m, lbValue s, isize index) {
 	return lb_emit_epi(m, s, index);
 	return lb_emit_epi(m, s, index);
 }
 }
 
 
-lbValue lb_emit_ptr_offset(lbProcedure *p, lbValue ptr, lbValue index) {
+gb_internal lbValue lb_emit_ptr_offset(lbProcedure *p, lbValue ptr, lbValue index) {
 	index = lb_emit_conv(p, index, t_int);
 	index = lb_emit_conv(p, index, t_int);
 	LLVMValueRef indices[1] = {index.value};
 	LLVMValueRef indices[1] = {index.value};
 	lbValue res = {};
 	lbValue res = {};
@@ -1373,7 +1365,7 @@ lbValue lb_emit_ptr_offset(lbProcedure *p, lbValue ptr, lbValue index) {
 	return res;
 	return res;
 }
 }
 
 
-lbValue lb_emit_matrix_epi(lbProcedure *p, lbValue s, isize row, isize column) {
+gb_internal lbValue lb_emit_matrix_epi(lbProcedure *p, lbValue s, isize row, isize column) {
 	Type *t = s.type;
 	Type *t = s.type;
 	GB_ASSERT(is_type_pointer(t));
 	GB_ASSERT(is_type_pointer(t));
 	Type *mt = base_type(type_deref(t));
 	Type *mt = base_type(type_deref(t));
@@ -1391,7 +1383,7 @@ lbValue lb_emit_matrix_epi(lbProcedure *p, lbValue s, isize row, isize column) {
 	return lb_emit_epi(p, s, offset);
 	return lb_emit_epi(p, s, offset);
 }
 }
 
 
-lbValue lb_emit_matrix_ep(lbProcedure *p, lbValue s, lbValue row, lbValue column) {
+gb_internal lbValue lb_emit_matrix_ep(lbProcedure *p, lbValue s, lbValue row, lbValue column) {
 	Type *t = s.type;
 	Type *t = s.type;
 	GB_ASSERT(is_type_pointer(t));
 	GB_ASSERT(is_type_pointer(t));
 	Type *mt = base_type(type_deref(t));
 	Type *mt = base_type(type_deref(t));
@@ -1423,7 +1415,7 @@ lbValue lb_emit_matrix_ep(lbProcedure *p, lbValue s, lbValue row, lbValue column
 }
 }
 
 
 
 
-lbValue lb_emit_matrix_ev(lbProcedure *p, lbValue s, isize row, isize column) {
+gb_internal lbValue lb_emit_matrix_ev(lbProcedure *p, lbValue s, isize row, isize column) {
 	Type *st = base_type(s.type);
 	Type *st = base_type(s.type);
 	GB_ASSERT_MSG(is_type_matrix(st), "%s", type_to_string(st));
 	GB_ASSERT_MSG(is_type_matrix(st), "%s", type_to_string(st));
 	
 	
@@ -1433,14 +1425,14 @@ lbValue lb_emit_matrix_ev(lbProcedure *p, lbValue s, isize row, isize column) {
 }
 }
 
 
 
 
-void lb_fill_slice(lbProcedure *p, lbAddr const &slice, lbValue base_elem, lbValue len) {
+gb_internal void lb_fill_slice(lbProcedure *p, lbAddr const &slice, lbValue base_elem, lbValue len) {
 	Type *t = lb_addr_type(slice);
 	Type *t = lb_addr_type(slice);
 	GB_ASSERT(is_type_slice(t));
 	GB_ASSERT(is_type_slice(t));
 	lbValue ptr = lb_addr_get_ptr(p, slice);
 	lbValue ptr = lb_addr_get_ptr(p, slice);
 	lb_emit_store(p, lb_emit_struct_ep(p, ptr, 0), base_elem);
 	lb_emit_store(p, lb_emit_struct_ep(p, ptr, 0), base_elem);
 	lb_emit_store(p, lb_emit_struct_ep(p, ptr, 1), len);
 	lb_emit_store(p, lb_emit_struct_ep(p, ptr, 1), len);
 }
 }
-void lb_fill_string(lbProcedure *p, lbAddr const &string, lbValue base_elem, lbValue len) {
+gb_internal void lb_fill_string(lbProcedure *p, lbAddr const &string, lbValue base_elem, lbValue len) {
 	Type *t = lb_addr_type(string);
 	Type *t = lb_addr_type(string);
 	GB_ASSERT(is_type_string(t));
 	GB_ASSERT(is_type_string(t));
 	lbValue ptr = lb_addr_get_ptr(p, string);
 	lbValue ptr = lb_addr_get_ptr(p, string);
@@ -1448,18 +1440,18 @@ void lb_fill_string(lbProcedure *p, lbAddr const &string, lbValue base_elem, lbV
 	lb_emit_store(p, lb_emit_struct_ep(p, ptr, 1), len);
 	lb_emit_store(p, lb_emit_struct_ep(p, ptr, 1), len);
 }
 }
 
 
-lbValue lb_string_elem(lbProcedure *p, lbValue string) {
+gb_internal lbValue lb_string_elem(lbProcedure *p, lbValue string) {
 	Type *t = base_type(string.type);
 	Type *t = base_type(string.type);
 	GB_ASSERT(t->kind == Type_Basic && t->Basic.kind == Basic_string);
 	GB_ASSERT(t->kind == Type_Basic && t->Basic.kind == Basic_string);
 	return lb_emit_struct_ev(p, string, 0);
 	return lb_emit_struct_ev(p, string, 0);
 }
 }
-lbValue lb_string_len(lbProcedure *p, lbValue string) {
+gb_internal lbValue lb_string_len(lbProcedure *p, lbValue string) {
 	Type *t = base_type(string.type);
 	Type *t = base_type(string.type);
 	GB_ASSERT_MSG(t->kind == Type_Basic && t->Basic.kind == Basic_string, "%s", type_to_string(t));
 	GB_ASSERT_MSG(t->kind == Type_Basic && t->Basic.kind == Basic_string, "%s", type_to_string(t));
 	return lb_emit_struct_ev(p, string, 1);
 	return lb_emit_struct_ev(p, string, 1);
 }
 }
 
 
-lbValue lb_cstring_len(lbProcedure *p, lbValue value) {
+gb_internal lbValue lb_cstring_len(lbProcedure *p, lbValue value) {
 	GB_ASSERT(is_type_cstring(value.type));
 	GB_ASSERT(is_type_cstring(value.type));
 	auto args = array_make<lbValue>(permanent_allocator(), 1);
 	auto args = array_make<lbValue>(permanent_allocator(), 1);
 	args[0] = lb_emit_conv(p, value, t_cstring);
 	args[0] = lb_emit_conv(p, value, t_cstring);
@@ -1467,43 +1459,39 @@ lbValue lb_cstring_len(lbProcedure *p, lbValue value) {
 }
 }
 
 
 
 
-lbValue lb_array_elem(lbProcedure *p, lbValue array_ptr) {
+gb_internal lbValue lb_array_elem(lbProcedure *p, lbValue array_ptr) {
 	Type *t = type_deref(array_ptr.type);
 	Type *t = type_deref(array_ptr.type);
 	GB_ASSERT(is_type_array(t));
 	GB_ASSERT(is_type_array(t));
 	return lb_emit_struct_ep(p, array_ptr, 0);
 	return lb_emit_struct_ep(p, array_ptr, 0);
 }
 }
 
 
-lbValue lb_slice_elem(lbProcedure *p, lbValue slice) {
+gb_internal lbValue lb_slice_elem(lbProcedure *p, lbValue slice) {
 	GB_ASSERT(is_type_slice(slice.type));
 	GB_ASSERT(is_type_slice(slice.type));
 	return lb_emit_struct_ev(p, slice, 0);
 	return lb_emit_struct_ev(p, slice, 0);
 }
 }
-lbValue lb_slice_len(lbProcedure *p, lbValue slice) {
+gb_internal lbValue lb_slice_len(lbProcedure *p, lbValue slice) {
 	GB_ASSERT(is_type_slice(slice.type) || is_type_relative_slice(slice.type));
 	GB_ASSERT(is_type_slice(slice.type) || is_type_relative_slice(slice.type));
 	return lb_emit_struct_ev(p, slice, 1);
 	return lb_emit_struct_ev(p, slice, 1);
 }
 }
-lbValue lb_dynamic_array_elem(lbProcedure *p, lbValue da) {
+gb_internal lbValue lb_dynamic_array_elem(lbProcedure *p, lbValue da) {
 	GB_ASSERT(is_type_dynamic_array(da.type));
 	GB_ASSERT(is_type_dynamic_array(da.type));
 	return lb_emit_struct_ev(p, da, 0);
 	return lb_emit_struct_ev(p, da, 0);
 }
 }
-lbValue lb_dynamic_array_len(lbProcedure *p, lbValue da) {
+gb_internal lbValue lb_dynamic_array_len(lbProcedure *p, lbValue da) {
 	GB_ASSERT(is_type_dynamic_array(da.type));
 	GB_ASSERT(is_type_dynamic_array(da.type));
 	return lb_emit_struct_ev(p, da, 1);
 	return lb_emit_struct_ev(p, da, 1);
 }
 }
-lbValue lb_dynamic_array_cap(lbProcedure *p, lbValue da) {
+gb_internal lbValue lb_dynamic_array_cap(lbProcedure *p, lbValue da) {
 	GB_ASSERT(is_type_dynamic_array(da.type));
 	GB_ASSERT(is_type_dynamic_array(da.type));
 	return lb_emit_struct_ev(p, da, 2);
 	return lb_emit_struct_ev(p, da, 2);
 }
 }
-lbValue lb_dynamic_array_allocator(lbProcedure *p, lbValue da) {
-	GB_ASSERT(is_type_dynamic_array(da.type));
-	return lb_emit_struct_ev(p, da, 3);
-}
 
 
-lbValue lb_map_len(lbProcedure *p, lbValue value) {
+gb_internal lbValue lb_map_len(lbProcedure *p, lbValue value) {
 	GB_ASSERT_MSG(is_type_map(value.type) || are_types_identical(value.type, t_raw_map), "%s", type_to_string(value.type));
 	GB_ASSERT_MSG(is_type_map(value.type) || are_types_identical(value.type, t_raw_map), "%s", type_to_string(value.type));
 	lbValue len = lb_emit_struct_ev(p, value, 1);
 	lbValue len = lb_emit_struct_ev(p, value, 1);
 	return lb_emit_conv(p, len, t_int);
 	return lb_emit_conv(p, len, t_int);
 }
 }
-lbValue lb_map_len_ptr(lbProcedure *p, lbValue map_ptr) {
+gb_internal lbValue lb_map_len_ptr(lbProcedure *p, lbValue map_ptr) {
 	Type *type = map_ptr.type;
 	Type *type = map_ptr.type;
 	GB_ASSERT(is_type_pointer(type));
 	GB_ASSERT(is_type_pointer(type));
 	type = type_deref(type);
 	type = type_deref(type);
@@ -1511,7 +1499,7 @@ lbValue lb_map_len_ptr(lbProcedure *p, lbValue map_ptr) {
 	return lb_emit_struct_ep(p, map_ptr, 1);
 	return lb_emit_struct_ep(p, map_ptr, 1);
 }
 }
 
 
-lbValue lb_map_cap(lbProcedure *p, lbValue value) {
+gb_internal lbValue lb_map_cap(lbProcedure *p, lbValue value) {
 	GB_ASSERT_MSG(is_type_map(value.type) || are_types_identical(value.type, t_raw_map), "%s", type_to_string(value.type));
 	GB_ASSERT_MSG(is_type_map(value.type) || are_types_identical(value.type, t_raw_map), "%s", type_to_string(value.type));
 	lbValue zero = lb_const_int(p->module, t_uintptr, 0);
 	lbValue zero = lb_const_int(p->module, t_uintptr, 0);
 	lbValue one = lb_const_int(p->module, t_uintptr, 1);
 	lbValue one = lb_const_int(p->module, t_uintptr, 1);
@@ -1525,7 +1513,7 @@ lbValue lb_map_cap(lbProcedure *p, lbValue value) {
 	return lb_emit_conv(p, lb_emit_select(p, cmp, zero, cap), t_int);
 	return lb_emit_conv(p, lb_emit_select(p, cmp, zero, cap), t_int);
 }
 }
 
 
-lbValue lb_map_data_uintptr(lbProcedure *p, lbValue value) {
+gb_internal lbValue lb_map_data_uintptr(lbProcedure *p, lbValue value) {
 	GB_ASSERT(is_type_map(value.type) || are_types_identical(value.type, t_raw_map));
 	GB_ASSERT(is_type_map(value.type) || are_types_identical(value.type, t_raw_map));
 	lbValue data = lb_emit_struct_ev(p, value, 0);
 	lbValue data = lb_emit_struct_ev(p, value, 0);
 	u64 mask_value = 0;
 	u64 mask_value = 0;
@@ -1539,7 +1527,7 @@ lbValue lb_map_data_uintptr(lbProcedure *p, lbValue value) {
 }
 }
 
 
 
 
-lbValue lb_soa_struct_len(lbProcedure *p, lbValue value) {
+gb_internal lbValue lb_soa_struct_len(lbProcedure *p, lbValue value) {
 	Type *t = base_type(value.type);
 	Type *t = base_type(value.type);
 	bool is_ptr = false;
 	bool is_ptr = false;
 	if (is_type_pointer(t)) {
 	if (is_type_pointer(t)) {
@@ -1572,7 +1560,7 @@ lbValue lb_soa_struct_len(lbProcedure *p, lbValue value) {
 	return lb_emit_struct_ev(p, value, cast(i32)n);
 	return lb_emit_struct_ev(p, value, cast(i32)n);
 }
 }
 
 
-lbValue lb_soa_struct_cap(lbProcedure *p, lbValue value) {
+gb_internal lbValue lb_soa_struct_cap(lbProcedure *p, lbValue value) {
 	Type *t = base_type(value.type);
 	Type *t = base_type(value.type);
 
 
 	bool is_ptr = false;
 	bool is_ptr = false;
@@ -1604,7 +1592,7 @@ lbValue lb_soa_struct_cap(lbProcedure *p, lbValue value) {
 	return lb_emit_struct_ev(p, value, cast(i32)n);
 	return lb_emit_struct_ev(p, value, cast(i32)n);
 }
 }
 
 
-lbValue lb_emit_mul_add(lbProcedure *p, lbValue a, lbValue b, lbValue c, Type *t) {
+gb_internal lbValue lb_emit_mul_add(lbProcedure *p, lbValue a, lbValue b, lbValue c, Type *t) {
 	lbModule *m = p->module;
 	lbModule *m = p->module;
 	
 	
 	a = lb_emit_conv(p, a, t);
 	a = lb_emit_conv(p, a, t);
@@ -1647,7 +1635,7 @@ lbValue lb_emit_mul_add(lbProcedure *p, lbValue a, lbValue b, lbValue c, Type *t
 	}
 	}
 }
 }
 
 
-LLVMValueRef llvm_mask_iota(lbModule *m, unsigned start, unsigned count) {
+gb_internal LLVMValueRef llvm_mask_iota(lbModule *m, unsigned start, unsigned count) {
 	auto iota = slice_make<LLVMValueRef>(temporary_allocator(), count);
 	auto iota = slice_make<LLVMValueRef>(temporary_allocator(), count);
 	for (unsigned i = 0; i < count; i++) {
 	for (unsigned i = 0; i < count; i++) {
 		iota[i] = lb_const_int(m, t_u32, start+i).value;
 		iota[i] = lb_const_int(m, t_u32, start+i).value;
@@ -1655,7 +1643,7 @@ LLVMValueRef llvm_mask_iota(lbModule *m, unsigned start, unsigned count) {
 	return LLVMConstVector(iota.data, count);
 	return LLVMConstVector(iota.data, count);
 }
 }
 
 
-LLVMValueRef llvm_mask_zero(lbModule *m, unsigned count) {
+gb_internal LLVMValueRef llvm_mask_zero(lbModule *m, unsigned count) {
 	return LLVMConstNull(LLVMVectorType(lb_type(m, t_u32), count));
 	return LLVMConstNull(LLVMVectorType(lb_type(m, t_u32), count));
 }
 }
 
 
@@ -1663,16 +1651,16 @@ LLVMValueRef llvm_mask_zero(lbModule *m, unsigned count) {
 // #define LLVM_VECTOR_DUMMY_VALUE(type) LLVMConstNull((type))
 // #define LLVM_VECTOR_DUMMY_VALUE(type) LLVMConstNull((type))
 
 
 
 
-LLVMValueRef llvm_basic_shuffle(lbProcedure *p, LLVMValueRef vector, LLVMValueRef mask) {
+gb_internal LLVMValueRef llvm_basic_shuffle(lbProcedure *p, LLVMValueRef vector, LLVMValueRef mask) {
 	return LLVMBuildShuffleVector(p->builder, vector, LLVM_VECTOR_DUMMY_VALUE(LLVMTypeOf(vector)), mask, "");
 	return LLVMBuildShuffleVector(p->builder, vector, LLVM_VECTOR_DUMMY_VALUE(LLVMTypeOf(vector)), mask, "");
 }
 }
-LLVMValueRef llvm_basic_const_shuffle(LLVMValueRef vector, LLVMValueRef mask) {
+gb_internal LLVMValueRef llvm_basic_const_shuffle(LLVMValueRef vector, LLVMValueRef mask) {
 	return LLVMConstShuffleVector(vector, LLVM_VECTOR_DUMMY_VALUE(LLVMTypeOf(vector)), mask);
 	return LLVMConstShuffleVector(vector, LLVM_VECTOR_DUMMY_VALUE(LLVMTypeOf(vector)), mask);
 }
 }
 
 
 
 
 
 
-LLVMValueRef llvm_vector_broadcast(lbProcedure *p, LLVMValueRef value, unsigned count) {
+gb_internal LLVMValueRef llvm_vector_broadcast(lbProcedure *p, LLVMValueRef value, unsigned count) {
 	GB_ASSERT(count > 0);
 	GB_ASSERT(count > 0);
 	if (LLVMIsConstant(value)) {
 	if (LLVMIsConstant(value)) {
 		LLVMValueRef single = LLVMConstVector(&value, 1);
 		LLVMValueRef single = LLVMConstVector(&value, 1);
@@ -1692,7 +1680,7 @@ LLVMValueRef llvm_vector_broadcast(lbProcedure *p, LLVMValueRef value, unsigned
 	return llvm_basic_shuffle(p, single, mask);
 	return llvm_basic_shuffle(p, single, mask);
 }
 }
 
 
-LLVMValueRef llvm_vector_shuffle_reduction(lbProcedure *p, LLVMValueRef value, LLVMOpcode op_code) {
+gb_internal LLVMValueRef llvm_vector_shuffle_reduction(lbProcedure *p, LLVMValueRef value, LLVMOpcode op_code) {
 	LLVMTypeRef original_vector_type = LLVMTypeOf(value);
 	LLVMTypeRef original_vector_type = LLVMTypeOf(value);
 	
 	
 	GB_ASSERT(LLVMGetTypeKind(original_vector_type) == LLVMVectorTypeKind);
 	GB_ASSERT(LLVMGetTypeKind(original_vector_type) == LLVMVectorTypeKind);
@@ -1719,7 +1707,7 @@ LLVMValueRef llvm_vector_shuffle_reduction(lbProcedure *p, LLVMValueRef value, L
 	return LLVMBuildExtractElement(p->builder, value, v_zero32, "");
 	return LLVMBuildExtractElement(p->builder, value, v_zero32, "");
 }
 }
 
 
-LLVMValueRef llvm_vector_expand_to_power_of_two(lbProcedure *p, LLVMValueRef value) {
+gb_internal LLVMValueRef llvm_vector_expand_to_power_of_two(lbProcedure *p, LLVMValueRef value) {
 	LLVMTypeRef vector_type = LLVMTypeOf(value);
 	LLVMTypeRef vector_type = LLVMTypeOf(value);
 	unsigned len = LLVMGetVectorSize(vector_type);
 	unsigned len = LLVMGetVectorSize(vector_type);
 	if (len == 1) {
 	if (len == 1) {
@@ -1734,7 +1722,7 @@ LLVMValueRef llvm_vector_expand_to_power_of_two(lbProcedure *p, LLVMValueRef val
 	return LLVMBuildShuffleVector(p->builder, value, LLVMConstNull(vector_type), mask, "");
 	return LLVMBuildShuffleVector(p->builder, value, LLVMConstNull(vector_type), mask, "");
 }
 }
 
 
-LLVMValueRef llvm_vector_reduce_add(lbProcedure *p, LLVMValueRef value) {
+gb_internal LLVMValueRef llvm_vector_reduce_add(lbProcedure *p, LLVMValueRef value) {
 	LLVMTypeRef type = LLVMTypeOf(value);
 	LLVMTypeRef type = LLVMTypeOf(value);
 	GB_ASSERT(LLVMGetTypeKind(type) == LLVMVectorTypeKind);
 	GB_ASSERT(LLVMGetTypeKind(type) == LLVMVectorTypeKind);
 	LLVMTypeRef elem = OdinLLVMGetVectorElementType(type);
 	LLVMTypeRef elem = OdinLLVMGetVectorElementType(type);
@@ -1810,7 +1798,7 @@ LLVMValueRef llvm_vector_reduce_add(lbProcedure *p, LLVMValueRef value) {
 #endif
 #endif
 }
 }
 
 
-LLVMValueRef llvm_vector_add(lbProcedure *p, LLVMValueRef a, LLVMValueRef b) {
+gb_internal LLVMValueRef llvm_vector_add(lbProcedure *p, LLVMValueRef a, LLVMValueRef b) {
 	GB_ASSERT(LLVMTypeOf(a) == LLVMTypeOf(b));
 	GB_ASSERT(LLVMTypeOf(a) == LLVMTypeOf(b));
 	
 	
 	LLVMTypeRef elem = OdinLLVMGetVectorElementType(LLVMTypeOf(a));
 	LLVMTypeRef elem = OdinLLVMGetVectorElementType(LLVMTypeOf(a));
@@ -1821,7 +1809,7 @@ LLVMValueRef llvm_vector_add(lbProcedure *p, LLVMValueRef a, LLVMValueRef b) {
 	return LLVMBuildFAdd(p->builder, a, b, "");
 	return LLVMBuildFAdd(p->builder, a, b, "");
 }
 }
 
 
-LLVMValueRef llvm_vector_mul(lbProcedure *p, LLVMValueRef a, LLVMValueRef b) {
+gb_internal LLVMValueRef llvm_vector_mul(lbProcedure *p, LLVMValueRef a, LLVMValueRef b) {
 	GB_ASSERT(LLVMTypeOf(a) == LLVMTypeOf(b));
 	GB_ASSERT(LLVMTypeOf(a) == LLVMTypeOf(b));
 	
 	
 	LLVMTypeRef elem = OdinLLVMGetVectorElementType(LLVMTypeOf(a));
 	LLVMTypeRef elem = OdinLLVMGetVectorElementType(LLVMTypeOf(a));
@@ -1833,11 +1821,11 @@ LLVMValueRef llvm_vector_mul(lbProcedure *p, LLVMValueRef a, LLVMValueRef b) {
 }
 }
 
 
 
 
-LLVMValueRef llvm_vector_dot(lbProcedure *p, LLVMValueRef a, LLVMValueRef b) {
+gb_internal LLVMValueRef llvm_vector_dot(lbProcedure *p, LLVMValueRef a, LLVMValueRef b) {
 	return llvm_vector_reduce_add(p, llvm_vector_mul(p, a, b));
 	return llvm_vector_reduce_add(p, llvm_vector_mul(p, a, b));
 }
 }
 
 
-LLVMValueRef llvm_vector_mul_add(lbProcedure *p, LLVMValueRef a, LLVMValueRef b, LLVMValueRef c) {
+gb_internal LLVMValueRef llvm_vector_mul_add(lbProcedure *p, LLVMValueRef a, LLVMValueRef b, LLVMValueRef c) {
 
 
 	LLVMTypeRef t = LLVMTypeOf(a);
 	LLVMTypeRef t = LLVMTypeOf(a);
 	GB_ASSERT(t == LLVMTypeOf(b));
 	GB_ASSERT(t == LLVMTypeOf(b));
@@ -1871,7 +1859,7 @@ LLVMValueRef llvm_vector_mul_add(lbProcedure *p, LLVMValueRef a, LLVMValueRef b,
 	}
 	}
 }
 }
 
 
-LLVMValueRef llvm_get_inline_asm(LLVMTypeRef func_type, String const &str, String const &clobbers, bool has_side_effects=true, bool is_align_stack=false, LLVMInlineAsmDialect dialect=LLVMInlineAsmDialectATT) {
+gb_internal LLVMValueRef llvm_get_inline_asm(LLVMTypeRef func_type, String const &str, String const &clobbers, bool has_side_effects=true, bool is_align_stack=false, LLVMInlineAsmDialect dialect=LLVMInlineAsmDialectATT) {
 	return LLVMGetInlineAsm(func_type,
 	return LLVMGetInlineAsm(func_type,
 		cast(char *)str.text, cast(size_t)str.len,
 		cast(char *)str.text, cast(size_t)str.len,
 		cast(char *)clobbers.text, cast(size_t)clobbers.len,
 		cast(char *)clobbers.text, cast(size_t)clobbers.len,
@@ -1884,7 +1872,7 @@ LLVMValueRef llvm_get_inline_asm(LLVMTypeRef func_type, String const &str, Strin
 }
 }
 
 
 
 
-void lb_set_wasm_import_attributes(LLVMValueRef value, Entity *entity, String import_name) {
+gb_internal void lb_set_wasm_import_attributes(LLVMValueRef value, Entity *entity, String import_name) {
 	if (!is_arch_wasm()) {
 	if (!is_arch_wasm()) {
 		return;
 		return;
 	}
 	}
@@ -1906,7 +1894,7 @@ void lb_set_wasm_import_attributes(LLVMValueRef value, Entity *entity, String im
 }
 }
 
 
 
 
-void lb_set_wasm_export_attributes(LLVMValueRef value, String export_name) {
+gb_internal void lb_set_wasm_export_attributes(LLVMValueRef value, String export_name) {
 	if (!is_arch_wasm()) {
 	if (!is_arch_wasm()) {
 		return;
 		return;
 	}
 	}
@@ -1918,7 +1906,7 @@ void lb_set_wasm_export_attributes(LLVMValueRef value, String export_name) {
 
 
 
 
 
 
-lbAddr lb_handle_objc_find_or_register_selector(lbProcedure *p, String const &name) {
+gb_internal lbAddr lb_handle_objc_find_or_register_selector(lbProcedure *p, String const &name) {
 	lbAddr *found = string_map_get(&p->module->objc_selectors, name);
 	lbAddr *found = string_map_get(&p->module->objc_selectors, name);
 	if (found) {
 	if (found) {
 		return *found;
 		return *found;
@@ -1938,7 +1926,7 @@ lbAddr lb_handle_objc_find_or_register_selector(lbProcedure *p, String const &na
 	}
 	}
 }
 }
 
 
-lbValue lb_handle_objc_find_selector(lbProcedure *p, Ast *expr) {
+gb_internal lbValue lb_handle_objc_find_selector(lbProcedure *p, Ast *expr) {
 	ast_node(ce, CallExpr, expr);
 	ast_node(ce, CallExpr, expr);
 
 
 	auto tav = ce->args[0]->tav;
 	auto tav = ce->args[0]->tav;
@@ -1947,7 +1935,7 @@ lbValue lb_handle_objc_find_selector(lbProcedure *p, Ast *expr) {
 	return lb_addr_load(p, lb_handle_objc_find_or_register_selector(p, name));
 	return lb_addr_load(p, lb_handle_objc_find_or_register_selector(p, name));
 }
 }
 
 
-lbValue lb_handle_objc_register_selector(lbProcedure *p, Ast *expr) {
+gb_internal lbValue lb_handle_objc_register_selector(lbProcedure *p, Ast *expr) {
 	ast_node(ce, CallExpr, expr);
 	ast_node(ce, CallExpr, expr);
 	lbModule *m = p->module;
 	lbModule *m = p->module;
 
 
@@ -1964,7 +1952,7 @@ lbValue lb_handle_objc_register_selector(lbProcedure *p, Ast *expr) {
 	return lb_addr_load(p, dst);
 	return lb_addr_load(p, dst);
 }
 }
 
 
-lbAddr lb_handle_objc_find_or_register_class(lbProcedure *p, String const &name) {
+gb_internal lbAddr lb_handle_objc_find_or_register_class(lbProcedure *p, String const &name) {
 	lbAddr *found = string_map_get(&p->module->objc_classes, name);
 	lbAddr *found = string_map_get(&p->module->objc_classes, name);
 	if (found) {
 	if (found) {
 		return *found;
 		return *found;
@@ -1984,7 +1972,7 @@ lbAddr lb_handle_objc_find_or_register_class(lbProcedure *p, String const &name)
 	}
 	}
 }
 }
 
 
-lbValue lb_handle_objc_find_class(lbProcedure *p, Ast *expr) {
+gb_internal lbValue lb_handle_objc_find_class(lbProcedure *p, Ast *expr) {
 	ast_node(ce, CallExpr, expr);
 	ast_node(ce, CallExpr, expr);
 
 
 	auto tav = ce->args[0]->tav;
 	auto tav = ce->args[0]->tav;
@@ -1993,7 +1981,7 @@ lbValue lb_handle_objc_find_class(lbProcedure *p, Ast *expr) {
 	return lb_addr_load(p, lb_handle_objc_find_or_register_class(p, name));
 	return lb_addr_load(p, lb_handle_objc_find_or_register_class(p, name));
 }
 }
 
 
-lbValue lb_handle_objc_register_class(lbProcedure *p, Ast *expr) {
+gb_internal lbValue lb_handle_objc_register_class(lbProcedure *p, Ast *expr) {
 	ast_node(ce, CallExpr, expr);
 	ast_node(ce, CallExpr, expr);
 	lbModule *m = p->module;
 	lbModule *m = p->module;
 
 
@@ -2013,7 +2001,7 @@ lbValue lb_handle_objc_register_class(lbProcedure *p, Ast *expr) {
 }
 }
 
 
 
 
-lbValue lb_handle_objc_id(lbProcedure *p, Ast *expr) {
+gb_internal lbValue lb_handle_objc_id(lbProcedure *p, Ast *expr) {
 	TypeAndValue const &tav = type_and_value_of_expr(expr);
 	TypeAndValue const &tav = type_and_value_of_expr(expr);
 	if (tav.mode == Addressing_Type) {
 	if (tav.mode == Addressing_Type) {
 		Type *type = tav.type;
 		Type *type = tav.type;
@@ -2044,7 +2032,7 @@ lbValue lb_handle_objc_id(lbProcedure *p, Ast *expr) {
 	return lb_build_expr(p, expr);
 	return lb_build_expr(p, expr);
 }
 }
 
 
-lbValue lb_handle_objc_send(lbProcedure *p, Ast *expr) {
+gb_internal lbValue lb_handle_objc_send(lbProcedure *p, Ast *expr) {
 	ast_node(ce, CallExpr, expr);
 	ast_node(ce, CallExpr, expr);
 
 
 	lbModule *m = p->module;
 	lbModule *m = p->module;
@@ -2087,7 +2075,7 @@ lbValue lb_handle_objc_send(lbProcedure *p, Ast *expr) {
 
 
 
 
 
 
-LLVMAtomicOrdering llvm_atomic_ordering_from_odin(ExactValue const &value) {
+gb_internal LLVMAtomicOrdering llvm_atomic_ordering_from_odin(ExactValue const &value) {
 	GB_ASSERT(value.kind == ExactValue_Integer);
 	GB_ASSERT(value.kind == ExactValue_Integer);
 	i64 v = exact_value_to_i64(value);
 	i64 v = exact_value_to_i64(value);
 	switch (v) {
 	switch (v) {
@@ -2103,7 +2091,7 @@ LLVMAtomicOrdering llvm_atomic_ordering_from_odin(ExactValue const &value) {
 }
 }
 
 
 
 
-LLVMAtomicOrdering llvm_atomic_ordering_from_odin(Ast *expr) {
+gb_internal LLVMAtomicOrdering llvm_atomic_ordering_from_odin(Ast *expr) {
 	ExactValue value = type_and_value_of_expr(expr).value;
 	ExactValue value = type_and_value_of_expr(expr).value;
 	return llvm_atomic_ordering_from_odin(value);
 	return llvm_atomic_ordering_from_odin(value);
 }
 }

+ 30 - 89
src/main.cpp

@@ -3,25 +3,32 @@
 #include "common.cpp"
 #include "common.cpp"
 #include "timings.cpp"
 #include "timings.cpp"
 #include "tokenizer.cpp"
 #include "tokenizer.cpp"
+#if defined(GB_SYSTEM_WINDOWS)
+	#pragma warning(push)
+	#pragma warning(disable: 4505)
+#endif
 #include "big_int.cpp"
 #include "big_int.cpp"
+#if defined(GB_SYSTEM_WINDOWS)
+	#pragma warning(pop)
+#endif
 #include "exact_value.cpp"
 #include "exact_value.cpp"
 #include "build_settings.cpp"
 #include "build_settings.cpp"
 
 
 gb_global ThreadPool global_thread_pool;
 gb_global ThreadPool global_thread_pool;
-void init_global_thread_pool(void) {
+gb_internal void init_global_thread_pool(void) {
 	isize thread_count = gb_max(build_context.thread_count, 1);
 	isize thread_count = gb_max(build_context.thread_count, 1);
 	isize worker_count = thread_count-1; // NOTE(bill): The main thread will also be used for work
 	isize worker_count = thread_count-1; // NOTE(bill): The main thread will also be used for work
 	thread_pool_init(&global_thread_pool, permanent_allocator(), worker_count, "ThreadPoolWorker");
 	thread_pool_init(&global_thread_pool, permanent_allocator(), worker_count, "ThreadPoolWorker");
 }
 }
-bool global_thread_pool_add_task(WorkerTaskProc *proc, void *data) {
+gb_internal bool global_thread_pool_add_task(WorkerTaskProc *proc, void *data) {
 	return thread_pool_add_task(&global_thread_pool, proc, data);
 	return thread_pool_add_task(&global_thread_pool, proc, data);
 }
 }
-void global_thread_pool_wait(void) {
+gb_internal void global_thread_pool_wait(void) {
 	thread_pool_wait(&global_thread_pool);
 	thread_pool_wait(&global_thread_pool);
 }
 }
 
 
 
 
-void debugf(char const *fmt, ...) {
+gb_internal void debugf(char const *fmt, ...) {
 	if (build_context.show_debug_messages) {
 	if (build_context.show_debug_messages) {
 		gb_printf_err("[DEBUG] ");
 		gb_printf_err("[DEBUG] ");
 		va_list va;
 		va_list va;
@@ -58,11 +65,10 @@ gb_global Timings global_timings = {0};
 	#endif
 	#endif
 #endif
 #endif
 
 
-#include "query_data.cpp"
 #include "bug_report.cpp"
 #include "bug_report.cpp"
 
 
 // NOTE(bill): 'name' is used in debugging and profiling modes
 // NOTE(bill): 'name' is used in debugging and profiling modes
-i32 system_exec_command_line_app(char const *name, char const *fmt, ...) {
+gb_internal i32 system_exec_command_line_app(char const *name, char const *fmt, ...) {
 	isize const cmd_cap = 64<<20; // 64 MiB should be more than enough
 	isize const cmd_cap = 64<<20; // 64 MiB should be more than enough
 	char *cmd_line = gb_alloc_array(gb_heap_allocator(), char, cmd_cap);
 	char *cmd_line = gb_alloc_array(gb_heap_allocator(), char, cmd_cap);
 	isize cmd_len = 0;
 	isize cmd_len = 0;
@@ -124,7 +130,7 @@ i32 system_exec_command_line_app(char const *name, char const *fmt, ...) {
 }
 }
 
 
 
 
-i32 linker_stage(lbGenerator *gen) {
+gb_internal i32 linker_stage(lbGenerator *gen) {
 	i32 result = 0;
 	i32 result = 0;
 	Timings *timings = &global_timings;
 	Timings *timings = &global_timings;
 
 
@@ -524,7 +530,7 @@ i32 linker_stage(lbGenerator *gen) {
 	return result;
 	return result;
 }
 }
 
 
-Array<String> setup_args(int argc, char const **argv) {
+gb_internal Array<String> setup_args(int argc, char const **argv) {
 	gbAllocator a = heap_allocator();
 	gbAllocator a = heap_allocator();
 
 
 #if defined(GB_SYSTEM_WINDOWS)
 #if defined(GB_SYSTEM_WINDOWS)
@@ -553,7 +559,7 @@ Array<String> setup_args(int argc, char const **argv) {
 #endif
 #endif
 }
 }
 
 
-void print_usage_line(i32 indent, char const *fmt, ...) {
+gb_internal void print_usage_line(i32 indent, char const *fmt, ...) {
 	while (indent --> 0) {
 	while (indent --> 0) {
 		gb_printf_err("\t");
 		gb_printf_err("\t");
 	}
 	}
@@ -564,7 +570,7 @@ void print_usage_line(i32 indent, char const *fmt, ...) {
 	gb_printf_err("\n");
 	gb_printf_err("\n");
 }
 }
 
 
-void usage(String argv0) {
+gb_internal void usage(String argv0) {
 	print_usage_line(0, "%.*s is a tool for managing Odin source code", LIT(argv0));
 	print_usage_line(0, "%.*s is a tool for managing Odin source code", LIT(argv0));
 	print_usage_line(0, "Usage:");
 	print_usage_line(0, "Usage:");
 	print_usage_line(1, "%.*s command [arguments]", LIT(argv0));
 	print_usage_line(1, "%.*s command [arguments]", LIT(argv0));
@@ -573,7 +579,6 @@ void usage(String argv0) {
 	print_usage_line(1, "                  one must contain the program's entry point, all must be in the same package.");
 	print_usage_line(1, "                  one must contain the program's entry point, all must be in the same package.");
 	print_usage_line(1, "run               same as 'build', but also then runs the newly compiled executable.");
 	print_usage_line(1, "run               same as 'build', but also then runs the newly compiled executable.");
 	print_usage_line(1, "check             parse, and type check a directory of .odin files");
 	print_usage_line(1, "check             parse, and type check a directory of .odin files");
-	print_usage_line(1, "query             parse, type check, and output a .json file containing information about the program");
 	print_usage_line(1, "strip-semicolon   parse, type check, and remove unneeded semicolons from the entire program");
 	print_usage_line(1, "strip-semicolon   parse, type check, and remove unneeded semicolons from the entire program");
 	print_usage_line(1, "test              build and runs procedures with the attribute @(test) in the initial package");
 	print_usage_line(1, "test              build and runs procedures with the attribute @(test) in the initial package");
 	print_usage_line(1, "doc               generate documentation on a directory of .odin files");
 	print_usage_line(1, "doc               generate documentation on a directory of .odin files");
@@ -687,12 +692,12 @@ struct BuildFlag {
 };
 };
 
 
 
 
-void add_flag(Array<BuildFlag> *build_flags, BuildFlagKind kind, String name, BuildFlagParamKind param_kind, u32 command_support, bool allow_mulitple=false) {
+gb_internal void add_flag(Array<BuildFlag> *build_flags, BuildFlagKind kind, String name, BuildFlagParamKind param_kind, u32 command_support, bool allow_mulitple=false) {
 	BuildFlag flag = {kind, name, param_kind, command_support, allow_mulitple};
 	BuildFlag flag = {kind, name, param_kind, command_support, allow_mulitple};
 	array_add(build_flags, flag);
 	array_add(build_flags, flag);
 }
 }
 
 
-ExactValue build_param_to_exact_value(String name, String param) {
+gb_internal ExactValue build_param_to_exact_value(String name, String param) {
 	ExactValue value = {};
 	ExactValue value = {};
 
 
 	/*
 	/*
@@ -747,7 +752,7 @@ ExactValue build_param_to_exact_value(String name, String param) {
 }
 }
 
 
 // Writes a did-you-mean message for formerly deprecated flags.
 // Writes a did-you-mean message for formerly deprecated flags.
-void did_you_mean_flag(String flag) {
+gb_internal void did_you_mean_flag(String flag) {
 	gbAllocator a = heap_allocator();
 	gbAllocator a = heap_allocator();
 	String name = copy_string(a, flag);
 	String name = copy_string(a, flag);
 	defer (gb_free(a, name.text));
 	defer (gb_free(a, name.text));
@@ -760,7 +765,7 @@ void did_you_mean_flag(String flag) {
 	gb_printf_err("Unknown flag: '%.*s'\n", LIT(flag));
 	gb_printf_err("Unknown flag: '%.*s'\n", LIT(flag));
 }
 }
 
 
-bool parse_build_flags(Array<String> args) {
+gb_internal bool parse_build_flags(Array<String> args) {
 	auto build_flags = array_make<BuildFlag>(heap_allocator(), 0, BuildFlag_COUNT);
 	auto build_flags = array_make<BuildFlag>(heap_allocator(), 0, BuildFlag_COUNT);
 	add_flag(&build_flags, BuildFlag_Help,                    str_lit("help"),                      BuildFlagParam_None,    Command_all);
 	add_flag(&build_flags, BuildFlag_Help,                    str_lit("help"),                      BuildFlagParam_None,    Command_all);
 	add_flag(&build_flags, BuildFlag_SingleFile,              str_lit("file"),                      BuildFlagParam_None,    Command__does_build | Command__does_check);
 	add_flag(&build_flags, BuildFlag_SingleFile,              str_lit("file"),                      BuildFlagParam_None,    Command__does_build | Command__does_check);
@@ -817,12 +822,6 @@ bool parse_build_flags(Array<String> args) {
 
 
 	add_flag(&build_flags, BuildFlag_UseStaticMapCalls,       str_lit("use-static-map-calls"),      BuildFlagParam_None,    Command__does_check);
 	add_flag(&build_flags, BuildFlag_UseStaticMapCalls,       str_lit("use-static-map-calls"),      BuildFlagParam_None,    Command__does_check);
 
 
-
-	add_flag(&build_flags, BuildFlag_Compact,                 str_lit("compact"),                   BuildFlagParam_None,    Command_query);
-	add_flag(&build_flags, BuildFlag_GlobalDefinitions,       str_lit("global-definitions"),        BuildFlagParam_None,    Command_query);
-	add_flag(&build_flags, BuildFlag_GoToDefinitions,         str_lit("go-to-definitions"),         BuildFlagParam_None,    Command_query);
-
-
 	add_flag(&build_flags, BuildFlag_Short,                   str_lit("short"),                     BuildFlagParam_None,    Command_doc);
 	add_flag(&build_flags, BuildFlag_Short,                   str_lit("short"),                     BuildFlagParam_None,    Command_doc);
 	add_flag(&build_flags, BuildFlag_AllPackages,             str_lit("all-packages"),              BuildFlagParam_None,    Command_doc);
 	add_flag(&build_flags, BuildFlag_AllPackages,             str_lit("all-packages"),              BuildFlagParam_None,    Command_doc);
 	add_flag(&build_flags, BuildFlag_DocFormat,               str_lit("doc-format"),                BuildFlagParam_None,    Command_doc);
 	add_flag(&build_flags, BuildFlag_DocFormat,               str_lit("doc-format"),                BuildFlagParam_None,    Command_doc);
@@ -1445,39 +1444,6 @@ bool parse_build_flags(Array<String> args) {
 							build_context.strict_style_init_only = true;
 							build_context.strict_style_init_only = true;
 							break;
 							break;
 						}
 						}
-						case BuildFlag_Compact: {
-							if (!build_context.query_data_set_settings.ok) {
-								gb_printf_err("Invalid use of -compact flag, only allowed with 'odin query'\n");
-								bad_flags = true;
-							} else {
-								build_context.query_data_set_settings.compact = true;
-							}
-							break;
-						}
-						case BuildFlag_GlobalDefinitions: {
-							if (!build_context.query_data_set_settings.ok) {
-								gb_printf_err("Invalid use of -global-definitions flag, only allowed with 'odin query'\n");
-								bad_flags = true;
-							} else if (build_context.query_data_set_settings.kind != QueryDataSet_Invalid) {
-								gb_printf_err("Invalid use of -global-definitions flag, a previous flag for 'odin query' was set\n");
-								bad_flags = true;
-							} else {
-								build_context.query_data_set_settings.kind = QueryDataSet_GlobalDefinitions;
-							}
-							break;
-						}
-						case BuildFlag_GoToDefinitions: {
-							if (!build_context.query_data_set_settings.ok) {
-								gb_printf_err("Invalid use of -go-to-definitions flag, only allowed with 'odin query'\n");
-								bad_flags = true;
-							} else if (build_context.query_data_set_settings.kind != QueryDataSet_Invalid) {
-								gb_printf_err("Invalid use of -global-definitions flag, a previous flag for 'odin query' was set\n");
-								bad_flags = true;
-							} else {
-								build_context.query_data_set_settings.kind = QueryDataSet_GoToDefinitions;
-							}
-							break;
-						}
 						case BuildFlag_Short:
 						case BuildFlag_Short:
 							build_context.cmd_doc_flags |= CmdDocFlag_Short;
 							build_context.cmd_doc_flags |= CmdDocFlag_Short;
 							break;
 							break;
@@ -1638,20 +1604,10 @@ bool parse_build_flags(Array<String> args) {
 		gb_printf_err("`-export-timings:<format>` requires `-show-timings` or `-show-more-timings` to be present\n");
 		gb_printf_err("`-export-timings:<format>` requires `-show-timings` or `-show-more-timings` to be present\n");
 		bad_flags = true;
 		bad_flags = true;
 	}
 	}
-
-	if (build_context.query_data_set_settings.ok) {
-		if (build_context.query_data_set_settings.kind == QueryDataSet_Invalid) {
-			gb_printf_err("'odin query' requires a flag determining the kind of query data set to be returned\n");
-			gb_printf_err("\t-global-definitions : outputs a JSON file of global definitions\n");
-			gb_printf_err("\t-go-to-definitions  : outputs a OGTD binary file of go to definitions for identifiers within an Odin project\n");
-			bad_flags = true;
-		}
-	}
-
 	return !bad_flags;
 	return !bad_flags;
 }
 }
 
 
-void timings_export_all(Timings *t, Checker *c, bool timings_are_finalized = false) {
+gb_internal void timings_export_all(Timings *t, Checker *c, bool timings_are_finalized = false) {
 	GB_ASSERT((!(build_context.export_timings_format == TimingsExportUnspecified) && build_context.export_timings_file.len > 0));
 	GB_ASSERT((!(build_context.export_timings_format == TimingsExportUnspecified) && build_context.export_timings_file.len > 0));
 
 
 	/*
 	/*
@@ -1749,7 +1705,7 @@ void timings_export_all(Timings *t, Checker *c, bool timings_are_finalized = fal
 	gb_printf("Done.\n");
 	gb_printf("Done.\n");
 }
 }
 
 
-void show_timings(Checker *c, Timings *t) {
+gb_internal void show_timings(Checker *c, Timings *t) {
 	Parser *p      = c->parser;
 	Parser *p      = c->parser;
 	isize lines    = p->total_line_count;
 	isize lines    = p->total_line_count;
 	isize tokens   = p->total_token_count;
 	isize tokens   = p->total_token_count;
@@ -1878,7 +1834,7 @@ void show_timings(Checker *c, Timings *t) {
 	}
 	}
 }
 }
 
 
-void remove_temp_files(lbGenerator *gen) {
+gb_internal void remove_temp_files(lbGenerator *gen) {
 	if (build_context.keep_temp_files) return;
 	if (build_context.keep_temp_files) return;
 
 
 	TIME_SECTION("remove keep temp files");
 	TIME_SECTION("remove keep temp files");
@@ -1902,7 +1858,7 @@ void remove_temp_files(lbGenerator *gen) {
 }
 }
 
 
 
 
-void print_show_help(String const arg0, String const &command) {
+gb_internal void print_show_help(String const arg0, String const &command) {
 	print_usage_line(0, "%.*s is a tool for managing Odin source code", LIT(arg0));
 	print_usage_line(0, "%.*s is a tool for managing Odin source code", LIT(arg0));
 	print_usage_line(0, "Usage:");
 	print_usage_line(0, "Usage:");
 	print_usage_line(1, "%.*s %.*s [arguments]", LIT(arg0), LIT(command));
 	print_usage_line(1, "%.*s %.*s [arguments]", LIT(arg0), LIT(command));
@@ -1931,8 +1887,6 @@ void print_show_help(String const arg0, String const &command) {
 		print_usage_line(3, "odin check filename.odin -file  # Type check single-file package, must contain entry point.");
 		print_usage_line(3, "odin check filename.odin -file  # Type check single-file package, must contain entry point.");
 	} else if (command == "test") {
 	} else if (command == "test") {
 		print_usage_line(1, "test      Build and runs procedures with the attribute @(test) in the initial package");
 		print_usage_line(1, "test      Build and runs procedures with the attribute @(test) in the initial package");
-	} else if (command == "query") {
-		print_usage_line(1, "query     [experimental] Parse, type check, and output a .json file containing information about the program");
 	} else if (command == "doc") {
 	} else if (command == "doc") {
 		print_usage_line(1, "doc       generate documentation from a directory of .odin files");
 		print_usage_line(1, "doc       generate documentation from a directory of .odin files");
 		print_usage_line(2, "Examples:");
 		print_usage_line(2, "Examples:");
@@ -2248,7 +2202,7 @@ void print_show_help(String const arg0, String const &command) {
 	}
 	}
 }
 }
 
 
-void print_show_unused(Checker *c) {
+gb_internal void print_show_unused(Checker *c) {
 	CheckerInfo *info = &c->info;
 	CheckerInfo *info = &c->info;
 
 
 	auto unused = array_make<Entity *>(permanent_allocator(), 0, info->entities.count);
 	auto unused = array_make<Entity *>(permanent_allocator(), 0, info->entities.count);
@@ -2322,7 +2276,7 @@ void print_show_unused(Checker *c) {
 	print_usage_line(0, "");
 	print_usage_line(0, "");
 }
 }
 
 
-bool check_env(void) {
+gb_internal bool check_env(void) {
 	gbAllocator a = heap_allocator();
 	gbAllocator a = heap_allocator();
 	char const *odin_root = gb_get_env("ODIN_ROOT", a);
 	char const *odin_root = gb_get_env("ODIN_ROOT", a);
 	defer (gb_free(a, cast(void *)odin_root));
 	defer (gb_free(a, cast(void *)odin_root));
@@ -2348,7 +2302,7 @@ struct StripSemicolonFile {
 	i64 written;
 	i64 written;
 };
 };
 
 
-gbFileError write_file_with_stripped_tokens(gbFile *f, AstFile *file, i64 *written_) {
+gb_internal gbFileError write_file_with_stripped_tokens(gbFile *f, AstFile *file, i64 *written_) {
 	i64 written = 0;
 	i64 written = 0;
 	gbFileError err = gbFileError_None;
 	gbFileError err = gbFileError_None;
 	u8 const *file_data = file->tokenizer.start;
 	u8 const *file_data = file->tokenizer.start;
@@ -2388,7 +2342,7 @@ gbFileError write_file_with_stripped_tokens(gbFile *f, AstFile *file, i64 *writt
 	return err;
 	return err;
 }
 }
 
 
-int strip_semicolons(Parser *parser) {
+gb_internal int strip_semicolons(Parser *parser) {
 	isize file_count = 0;
 	isize file_count = 0;
 	for_array(i, parser->packages) {
 	for_array(i, parser->packages) {
 		AstPackage *pkg = parser->packages[i];
 		AstPackage *pkg = parser->packages[i];
@@ -2627,15 +2581,6 @@ int main(int arg_count, char const **arg_ptr) {
 		build_context.command_kind = Command_strip_semicolon;
 		build_context.command_kind = Command_strip_semicolon;
 		build_context.no_output_files = true;
 		build_context.no_output_files = true;
 		init_filename = args[2];
 		init_filename = args[2];
-	} else if (command == "query") {
-		if (args.count < 3) {
-			usage(args[0]);
-			return 1;
-		}
-		build_context.command_kind = Command_query;
-		build_context.no_output_files = true;
-		build_context.query_data_set_settings.ok = true;
-		init_filename = args[2];
 	} else if (command == "doc") {
 	} else if (command == "doc") {
 		if (args.count < 3) {
 		if (args.count < 3) {
 			usage(args[0]);
 			usage(args[0]);
@@ -2824,12 +2769,8 @@ int main(int arg_count, char const **arg_ptr) {
 			print_show_unused(checker);
 			print_show_unused(checker);
 		}
 		}
 
 
-		if (build_context.query_data_set_settings.ok) {
-			generate_and_print_query_data(checker, &global_timings);
-		} else {
-			if (build_context.show_timings) {
-				show_timings(checker, &global_timings);
-			}
+		if (build_context.show_timings) {
+			show_timings(checker, &global_timings);
 		}
 		}
 
 
 		if (global_error_collector.count != 0) {
 		if (global_error_collector.count != 0) {

+ 20 - 20
src/microsoft_craziness.h

@@ -58,40 +58,40 @@ struct Find_Result {
 	String vs_library_path;
 	String vs_library_path;
 };
 };
 
 
-String mc_wstring_to_string(wchar_t const *str) {
+gb_internal String mc_wstring_to_string(wchar_t const *str) {
 	return string16_to_string(mc_allocator, make_string16_c(str));
 	return string16_to_string(mc_allocator, make_string16_c(str));
 }
 }
 
 
-String16 mc_string_to_wstring(String str) {
+gb_internal String16 mc_string_to_wstring(String str) {
 	return string_to_string16(mc_allocator, str);
 	return string_to_string16(mc_allocator, str);
 }
 }
 
 
-String mc_concat(String a, String b) {
+gb_internal String mc_concat(String a, String b) {
 	return concatenate_strings(mc_allocator, a, b);
 	return concatenate_strings(mc_allocator, a, b);
 }
 }
 
 
-String mc_concat(String a, String b, String c) {
+gb_internal String mc_concat(String a, String b, String c) {
 	return concatenate3_strings(mc_allocator, a, b, c);
 	return concatenate3_strings(mc_allocator, a, b, c);
 }
 }
 
 
-String mc_concat(String a, String b, String c, String d) {
+gb_internal String mc_concat(String a, String b, String c, String d) {
 	return concatenate4_strings(mc_allocator, a, b, c, d);
 	return concatenate4_strings(mc_allocator, a, b, c, d);
 }
 }
 
 
-String mc_get_env(String key) {
+gb_internal String mc_get_env(String key) {
 	char const * value = gb_get_env((char const *)key.text, mc_allocator);
 	char const * value = gb_get_env((char const *)key.text, mc_allocator);
 	return make_string_c(value);
 	return make_string_c(value);
 }
 }
 
 
-void mc_free(String str) {
+gb_internal void mc_free(String str) {
 	if (str.len) gb_free(mc_allocator, str.text);
 	if (str.len) gb_free(mc_allocator, str.text);
 }
 }
 
 
-void mc_free(String16 str) {
+gb_internal void mc_free(String16 str) {
 	if (str.len) gb_free(mc_allocator, str.text);
 	if (str.len) gb_free(mc_allocator, str.text);
 }
 }
 
 
-void mc_free_all() {
+gb_internal void mc_free_all() {
 	gb_free_all(mc_allocator);
 	gb_free_all(mc_allocator);
 }
 }
 
 
@@ -101,7 +101,7 @@ typedef struct _MC_Find_Data {
 } MC_Find_Data;
 } MC_Find_Data;
 
 
 
 
-HANDLE mc_find_first(String wildcard, MC_Find_Data *find_data) {
+gb_internal HANDLE mc_find_first(String wildcard, MC_Find_Data *find_data) {
  	WIN32_FIND_DATAW _find_data;
  	WIN32_FIND_DATAW _find_data;
 
 
  	String16 wildcard_wide = mc_string_to_wstring(wildcard);
  	String16 wildcard_wide = mc_string_to_wstring(wildcard);
@@ -115,7 +115,7 @@ HANDLE mc_find_first(String wildcard, MC_Find_Data *find_data) {
  	return handle;
  	return handle;
 }
 }
 
 
-bool mc_find_next(HANDLE handle, MC_Find_Data *find_data) {
+gb_internal bool mc_find_next(HANDLE handle, MC_Find_Data *find_data) {
  	WIN32_FIND_DATAW _find_data;
  	WIN32_FIND_DATAW _find_data;
  	bool success = !!FindNextFileW(handle, &_find_data);
  	bool success = !!FindNextFileW(handle, &_find_data);
 
 
@@ -124,7 +124,7 @@ bool mc_find_next(HANDLE handle, MC_Find_Data *find_data) {
  	return success;
  	return success;
 }
 }
 
 
-void mc_find_close(HANDLE handle) {
+gb_internal void mc_find_close(HANDLE handle) {
 	FindClose(handle);
 	FindClose(handle);
 }
 }
 
 
@@ -216,7 +216,7 @@ struct Version_Data {
 };
 };
 
 
 typedef void (*MC_Visit_Proc)(String short_name, String full_name, Version_Data *data);
 typedef void (*MC_Visit_Proc)(String short_name, String full_name, Version_Data *data);
-bool mc_visit_files(String dir_name, Version_Data *data, MC_Visit_Proc proc) {
+gb_internal bool mc_visit_files(String dir_name, Version_Data *data, MC_Visit_Proc proc) {
 
 
 	// Visit everything in one folder (non-recursively). If it's a directory
 	// Visit everything in one folder (non-recursively). If it's a directory
 	// that doesn't start with ".", call the visit proc on it. The visit proc
 	// that doesn't start with ".", call the visit proc on it. The visit proc
@@ -246,7 +246,7 @@ bool mc_visit_files(String dir_name, Version_Data *data, MC_Visit_Proc proc) {
 	return true;
 	return true;
 }
 }
 
 
-String find_windows_kit_root(HKEY key, String const version) {
+gb_internal String find_windows_kit_root(HKEY key, String const version) {
 	// Given a key to an already opened registry entry,
 	// Given a key to an already opened registry entry,
 	// get the value stored under the 'version' subkey.
 	// get the value stored under the 'version' subkey.
 	// If that's not the right terminology, hey, I never do registry stuff.
 	// If that's not the right terminology, hey, I never do registry stuff.
@@ -275,7 +275,7 @@ String find_windows_kit_root(HKEY key, String const version) {
 	return value;
 	return value;
 }
 }
 
 
-void win10_best(String short_name, String full_name, Version_Data *data) {
+gb_internal void win10_best(String short_name, String full_name, Version_Data *data) {
 	// Find the Windows 10 subdirectory with the highest version number.
 	// Find the Windows 10 subdirectory with the highest version number.
 
 
 	int i0, i1, i2, i3;
 	int i0, i1, i2, i3;
@@ -307,7 +307,7 @@ void win10_best(String short_name, String full_name, Version_Data *data) {
 	}
 	}
 }
 }
 
 
-void find_windows_kit_paths(Find_Result *result) {
+gb_internal void find_windows_kit_paths(Find_Result *result) {
 	bool sdk_found = false;
 	bool sdk_found = false;
 
 
 	HKEY main_key;
 	HKEY main_key;
@@ -355,7 +355,7 @@ void find_windows_kit_paths(Find_Result *result) {
 	}
 	}
 }
 }
 
 
-bool find_visual_studio_by_fighting_through_microsoft_craziness(Find_Result *result) {
+gb_internal bool find_visual_studio_by_fighting_through_microsoft_craziness(Find_Result *result) {
 	// The name of this procedure is kind of cryptic. Its purpose is
 	// The name of this procedure is kind of cryptic. Its purpose is
 	// to fight through Microsoft craziness. The things that the fine
 	// to fight through Microsoft craziness. The things that the fine
 	// Visual Studio team want you to do, JUST TO FIND A SINGLE FOLDER
 	// Visual Studio team want you to do, JUST TO FIND A SINGLE FOLDER
@@ -519,7 +519,7 @@ bool find_visual_studio_by_fighting_through_microsoft_craziness(Find_Result *res
 
 
 // NOTE(WalterPlinge): Environment variables can help to find Visual C++ and WinSDK paths for both
 // NOTE(WalterPlinge): Environment variables can help to find Visual C++ and WinSDK paths for both
 // official and portable installations (like mmozeiko's portable msvc script).
 // official and portable installations (like mmozeiko's portable msvc script).
-void find_windows_kit_paths_from_env_vars(Find_Result *result) {
+gb_internal void find_windows_kit_paths_from_env_vars(Find_Result *result) {
 	if (build_context.metrics.arch != TargetArch_amd64 && build_context.metrics.arch != TargetArch_i386) {
 	if (build_context.metrics.arch != TargetArch_amd64 && build_context.metrics.arch != TargetArch_i386) {
 		return;
 		return;
 	}
 	}
@@ -669,7 +669,7 @@ void find_windows_kit_paths_from_env_vars(Find_Result *result) {
 // NOTE(WalterPlinge): Environment variables can help to find Visual C++ and WinSDK paths for both
 // NOTE(WalterPlinge): Environment variables can help to find Visual C++ and WinSDK paths for both
 // official and portable installations (like mmozeiko's portable msvc script). This will only use
 // official and portable installations (like mmozeiko's portable msvc script). This will only use
 // the first paths it finds, and won't overwrite any values that `result` already has.
 // the first paths it finds, and won't overwrite any values that `result` already has.
-void find_visual_studio_paths_from_env_vars(Find_Result *result) {
+gb_internal void find_visual_studio_paths_from_env_vars(Find_Result *result) {
 	if (build_context.metrics.arch != TargetArch_amd64 && build_context.metrics.arch != TargetArch_i386) {
 	if (build_context.metrics.arch != TargetArch_amd64 && build_context.metrics.arch != TargetArch_i386) {
 		return;
 		return;
 	}
 	}
@@ -756,7 +756,7 @@ void find_visual_studio_paths_from_env_vars(Find_Result *result) {
 	}
 	}
 }
 }
 
 
-Find_Result find_visual_studio_and_windows_sdk() {
+gb_internal Find_Result find_visual_studio_and_windows_sdk() {
 	Find_Result r = {};
 	Find_Result r = {};
 	find_windows_kit_paths(&r);
 	find_windows_kit_paths(&r);
 	find_visual_studio_by_fighting_through_microsoft_craziness(&r);
 	find_visual_studio_by_fighting_through_microsoft_craziness(&r);

File diff suppressed because it is too large
+ 113 - 145
src/parser.cpp


+ 53 - 47
src/parser.hpp

@@ -62,15 +62,6 @@ enum PackageKind {
 	Package_Init,
 	Package_Init,
 };
 };
 
 
-struct ImportedPackage {
-	PackageKind kind;
-	String      path;
-	String      rel_path;
-	TokenPos    pos; // import
-	isize       index;
-};
-
-
 struct ImportedFile {
 struct ImportedFile {
 	AstPackage *pkg;
 	AstPackage *pkg;
 	FileInfo    fi;
 	FileInfo    fi;
@@ -99,7 +90,11 @@ struct AstFile {
 	Scope *      scope;
 	Scope *      scope;
 
 
 	Ast *        pkg_decl;
 	Ast *        pkg_decl;
+
 	String       fullpath;
 	String       fullpath;
+	String       filename;
+	String       directory;
+
 	Tokenizer    tokenizer;
 	Tokenizer    tokenizer;
 	Array<Token> tokens;
 	Array<Token> tokens;
 	isize        curr_token_index;
 	isize        curr_token_index;
@@ -109,6 +104,7 @@ struct AstFile {
 	Token        package_token;
 	Token        package_token;
 	String       package_name;
 	String       package_name;
 
 
+
 	// >= 0: In Expression
 	// >= 0: In Expression
 	// <  0: In Control Clause
 	// <  0: In Control Clause
 	// NOTE(bill): Used to prevent type literals in control clauses
 	// NOTE(bill): Used to prevent type literals in control clauses
@@ -136,9 +132,8 @@ struct AstFile {
 	CommentGroup *docs;             // current docs
 	CommentGroup *docs;             // current docs
 	Array<CommentGroup *> comments; // All the comments!
 	Array<CommentGroup *> comments; // All the comments!
 
 
-	// TODO(bill): make this a basic queue as it does not require
-	// any multiple thread capabilities
-	MPMCQueue<Ast *> delayed_decls_queues[AstDelayQueue_COUNT];
+	// This is effectively a queue but does not require any multi-threading capabilities
+	Array<Ast *> delayed_decls_queues[AstDelayQueue_COUNT];
 
 
 #define PARSER_MAX_FIX_COUNT 6
 #define PARSER_MAX_FIX_COUNT 6
 	isize    fix_count;
 	isize    fix_count;
@@ -177,6 +172,9 @@ struct AstPackage {
 	bool                  is_single_file;
 	bool                  is_single_file;
 	isize                 order;
 	isize                 order;
 
 
+	BlockingMutex         files_mutex;
+	BlockingMutex         foreign_files_mutex;
+
 	MPMCQueue<AstPackageExportedEntity> exported_entity_queue;
 	MPMCQueue<AstPackageExportedEntity> exported_entity_queue;
 
 
 	// NOTE(bill): Created/set in checker
 	// NOTE(bill): Created/set in checker
@@ -186,20 +184,33 @@ struct AstPackage {
 };
 };
 
 
 
 
+struct ParseFileErrorNode {
+	ParseFileErrorNode *next, *prev;
+	ParseFileError      err;
+};
+
 struct Parser {
 struct Parser {
-	String                    init_fullpath;
-	StringSet                 imported_files; // fullpath
-	Array<AstPackage *>       packages;
-	Array<ImportedPackage>    package_imports;
-	isize                     file_to_process_count;
-	isize                     total_token_count;
-	isize                     total_line_count;
-	BlockingMutex             wait_mutex;
-	BlockingMutex             import_mutex;
-	BlockingMutex             file_add_mutex;
-	BlockingMutex             file_decl_mutex;
-	BlockingMutex             packages_mutex;
-	MPMCQueue<ParseFileError> file_error_queue;
+	String                 init_fullpath;
+
+	StringSet              imported_files; // fullpath
+	BlockingMutex          imported_files_mutex;
+
+	Array<AstPackage *>    packages;
+	BlockingMutex          packages_mutex;
+
+	std::atomic<isize>     file_to_process_count;
+	std::atomic<isize>     total_token_count;
+	std::atomic<isize>     total_line_count;
+
+	// TODO(bill): What should this mutex be per?
+	//  * Parser
+	//  * Package
+	//  * File
+	BlockingMutex          file_decl_mutex;
+
+	BlockingMutex          file_error_mutex;
+	ParseFileErrorNode *   file_error_head;
+	ParseFileErrorNode *   file_error_tail;
 };
 };
 
 
 struct ParserWorkerData {
 struct ParserWorkerData {
@@ -258,7 +269,7 @@ enum ProcCallingConvention : i32 {
 	ProcCC_ForeignBlockDefault = -1,
 	ProcCC_ForeignBlockDefault = -1,
 };
 };
 
 
-char const *proc_calling_convention_strings[ProcCC_MAX] = {
+gb_global char const *proc_calling_convention_strings[ProcCC_MAX] = {
 	"",
 	"",
 	"odin",
 	"odin",
 	"contextless",
 	"contextless",
@@ -272,7 +283,7 @@ char const *proc_calling_convention_strings[ProcCC_MAX] = {
 	"sysv",
 	"sysv",
 };
 };
 
 
-ProcCallingConvention default_calling_convention(void) {
+gb_internal ProcCallingConvention default_calling_convention(void) {
 	return ProcCC_Odin;
 	return ProcCC_Odin;
 }
 }
 
 
@@ -332,7 +343,7 @@ enum InlineAsmDialectKind : u8 {
 	InlineAsmDialect_COUNT,
 	InlineAsmDialect_COUNT,
 };
 };
 
 
-char const *inline_asm_dialect_strings[InlineAsmDialect_COUNT] = {
+gb_global char const *inline_asm_dialect_strings[InlineAsmDialect_COUNT] = {
 	"",
 	"",
 	"att",
 	"att",
 	"intel",
 	"intel",
@@ -457,11 +468,6 @@ AST_KIND(_StmtBegin,     "", bool) \
 	AST_KIND(BadStmt,    "bad statement",                 struct { Token begin, end; }) \
 	AST_KIND(BadStmt,    "bad statement",                 struct { Token begin, end; }) \
 	AST_KIND(EmptyStmt,  "empty statement",               struct { Token token; }) \
 	AST_KIND(EmptyStmt,  "empty statement",               struct { Token token; }) \
 	AST_KIND(ExprStmt,   "expression statement",          struct { Ast *expr; } ) \
 	AST_KIND(ExprStmt,   "expression statement",          struct { Ast *expr; } ) \
-	AST_KIND(TagStmt,    "tag statement", struct { \
-		Token token; \
-		Token name; \
-		Ast * stmt; \
-	}) \
 	AST_KIND(AssignStmt, "assign statement", struct { \
 	AST_KIND(AssignStmt, "assign statement", struct { \
 		Token op; \
 		Token op; \
 		Slice<Ast *> lhs, rhs; \
 		Slice<Ast *> lhs, rhs; \
@@ -729,7 +735,7 @@ enum AstKind : u16 {
 	Ast_COUNT,
 	Ast_COUNT,
 };
 };
 
 
-String const ast_strings[] = {
+gb_global String const ast_strings[] = {
 	{cast(u8 *)"invalid node", gb_size_of("invalid node")},
 	{cast(u8 *)"invalid node", gb_size_of("invalid node")},
 #define AST_KIND(_kind_name_, name, ...) {cast(u8 *)name, gb_size_of(name)-1},
 #define AST_KIND(_kind_name_, name, ...) {cast(u8 *)name, gb_size_of(name)-1},
 	AST_KINDS
 	AST_KINDS
@@ -742,7 +748,7 @@ String const ast_strings[] = {
 #undef AST_KIND
 #undef AST_KIND
 
 
 
 
-isize const ast_variant_sizes[] = {
+gb_global isize const ast_variant_sizes[] = {
 	0,
 	0,
 #define AST_KIND(_kind_name_, name, ...) gb_size_of(GB_JOIN2(Ast, _kind_name_)),
 #define AST_KIND(_kind_name_, name, ...) gb_size_of(GB_JOIN2(Ast, _kind_name_)),
 	AST_KINDS
 	AST_KINDS
@@ -754,7 +760,7 @@ struct AstCommonStuff {
 	u8           state_flags;
 	u8           state_flags;
 	u8           viral_state_flags;
 	u8           viral_state_flags;
 	i32          file_id;
 	i32          file_id;
-	TypeAndValue tav; // TODO(bill): Make this a pointer to minimize 'Ast' size
+	TypeAndValue tav; // NOTE(bill): Making this a pointer is slower
 };
 };
 
 
 struct Ast {
 struct Ast {
@@ -762,7 +768,7 @@ struct Ast {
 	u8           state_flags;
 	u8           state_flags;
 	u8           viral_state_flags;
 	u8           viral_state_flags;
 	i32          file_id;
 	i32          file_id;
-	TypeAndValue tav; // TODO(bill): Make this a pointer to minimize 'Ast' size
+	TypeAndValue tav; // NOTE(bill): Making this a pointer is slower
 
 
 	// IMPORTANT NOTE(bill): This must be at the end since the AST is allocated to be size of the variant
 	// IMPORTANT NOTE(bill): This must be at the end since the AST is allocated to be size of the variant
 	union {
 	union {
@@ -793,33 +799,33 @@ struct Ast {
 #endif
 #endif
 
 
 
 
-gb_inline bool is_ast_expr(Ast *node) {
+gb_internal gb_inline bool is_ast_expr(Ast *node) {
 	return gb_is_between(node->kind, Ast__ExprBegin+1, Ast__ExprEnd-1);
 	return gb_is_between(node->kind, Ast__ExprBegin+1, Ast__ExprEnd-1);
 }
 }
-gb_inline bool is_ast_stmt(Ast *node) {
+gb_internal gb_inline bool is_ast_stmt(Ast *node) {
 	return gb_is_between(node->kind, Ast__StmtBegin+1, Ast__StmtEnd-1);
 	return gb_is_between(node->kind, Ast__StmtBegin+1, Ast__StmtEnd-1);
 }
 }
-gb_inline bool is_ast_complex_stmt(Ast *node) {
+gb_internal gb_inline bool is_ast_complex_stmt(Ast *node) {
 	return gb_is_between(node->kind, Ast__ComplexStmtBegin+1, Ast__ComplexStmtEnd-1);
 	return gb_is_between(node->kind, Ast__ComplexStmtBegin+1, Ast__ComplexStmtEnd-1);
 }
 }
-gb_inline bool is_ast_decl(Ast *node) {
+gb_internal gb_inline bool is_ast_decl(Ast *node) {
 	return gb_is_between(node->kind, Ast__DeclBegin+1, Ast__DeclEnd-1);
 	return gb_is_between(node->kind, Ast__DeclBegin+1, Ast__DeclEnd-1);
 }
 }
-gb_inline bool is_ast_type(Ast *node) {
+gb_internal gb_inline bool is_ast_type(Ast *node) {
 	return gb_is_between(node->kind, Ast__TypeBegin+1, Ast__TypeEnd-1);
 	return gb_is_between(node->kind, Ast__TypeBegin+1, Ast__TypeEnd-1);
 }
 }
-gb_inline bool is_ast_when_stmt(Ast *node) {
+gb_internal gb_inline bool is_ast_when_stmt(Ast *node) {
 	return node->kind == Ast_WhenStmt;
 	return node->kind == Ast_WhenStmt;
 }
 }
 
 
 gb_global gb_thread_local Arena global_thread_local_ast_arena = {};
 gb_global gb_thread_local Arena global_thread_local_ast_arena = {};
 
 
-gbAllocator ast_allocator(AstFile *f) {
+gb_internal gbAllocator ast_allocator(AstFile *f) {
 	Arena *arena = &global_thread_local_ast_arena;
 	Arena *arena = &global_thread_local_ast_arena;
 	return arena_allocator(arena);
 	return arena_allocator(arena);
 }
 }
 
 
-Ast *alloc_ast_node(AstFile *f, AstKind kind);
+gb_internal Ast *alloc_ast_node(AstFile *f, AstKind kind);
 
 
-gbString expr_to_string(Ast *expression);
-bool allow_field_separator(AstFile *f);
+gb_internal gbString expr_to_string(Ast *expression);
+gb_internal bool allow_field_separator(AstFile *f);

+ 2 - 4
src/parser_pos.cpp

@@ -1,4 +1,4 @@
-Token ast_token(Ast *node) {
+gb_internal Token ast_token(Ast *node) {
 	switch (node->kind) {
 	switch (node->kind) {
 	case Ast_Ident:          return node->Ident.token;
 	case Ast_Ident:          return node->Ident.token;
 	case Ast_Implicit:       return node->Implicit;
 	case Ast_Implicit:       return node->Implicit;
@@ -53,7 +53,6 @@ Token ast_token(Ast *node) {
 	case Ast_BadStmt:            return node->BadStmt.begin;
 	case Ast_BadStmt:            return node->BadStmt.begin;
 	case Ast_EmptyStmt:          return node->EmptyStmt.token;
 	case Ast_EmptyStmt:          return node->EmptyStmt.token;
 	case Ast_ExprStmt:           return ast_token(node->ExprStmt.expr);
 	case Ast_ExprStmt:           return ast_token(node->ExprStmt.expr);
-	case Ast_TagStmt:            return node->TagStmt.token;
 	case Ast_AssignStmt:         return node->AssignStmt.op;
 	case Ast_AssignStmt:         return node->AssignStmt.op;
 	case Ast_BlockStmt:          return node->BlockStmt.open;
 	case Ast_BlockStmt:          return node->BlockStmt.open;
 	case Ast_IfStmt:             return node->IfStmt.token;
 	case Ast_IfStmt:             return node->IfStmt.token;
@@ -197,7 +196,6 @@ Token ast_end_token(Ast *node) {
 	case Ast_BadStmt:            return node->BadStmt.end;
 	case Ast_BadStmt:            return node->BadStmt.end;
 	case Ast_EmptyStmt:          return node->EmptyStmt.token;
 	case Ast_EmptyStmt:          return node->EmptyStmt.token;
 	case Ast_ExprStmt:           return ast_end_token(node->ExprStmt.expr);
 	case Ast_ExprStmt:           return ast_end_token(node->ExprStmt.expr);
-	case Ast_TagStmt:            return ast_end_token(node->TagStmt.stmt);
 	case Ast_AssignStmt:
 	case Ast_AssignStmt:
 		if (node->AssignStmt.rhs.count > 0) {
 		if (node->AssignStmt.rhs.count > 0) {
 			return ast_end_token(node->AssignStmt.rhs[node->AssignStmt.rhs.count-1]);
 			return ast_end_token(node->AssignStmt.rhs[node->AssignStmt.rhs.count-1]);
@@ -360,6 +358,6 @@ Token ast_end_token(Ast *node) {
 	return empty_token;
 	return empty_token;
 }
 }
 
 
-TokenPos ast_end_pos(Ast *node) {
+gb_internal TokenPos ast_end_pos(Ast *node) {
 	return token_pos_end(ast_end_token(node));
 	return token_pos_end(ast_end_token(node));
 }
 }

+ 15 - 15
src/path.cpp

@@ -1,7 +1,7 @@
 /*
 /*
 	Path handling utilities.
 	Path handling utilities.
 */
 */
-String remove_extension_from_path(String const &s) {
+gb_internal String remove_extension_from_path(String const &s) {
 	for (isize i = s.len-1; i >= 0; i--) {
 	for (isize i = s.len-1; i >= 0; i--) {
 		if (s[i] == '.') {
 		if (s[i] == '.') {
 			return substring(s, 0, i);
 			return substring(s, 0, i);
@@ -10,7 +10,7 @@ String remove_extension_from_path(String const &s) {
 	return s;
 	return s;
 }
 }
 
 
-String remove_directory_from_path(String const &s) {
+gb_internal String remove_directory_from_path(String const &s) {
 	isize len = 0;
 	isize len = 0;
 	for (isize i = s.len-1; i >= 0; i--) {
 	for (isize i = s.len-1; i >= 0; i--) {
 		if (s[i] == '/' ||
 		if (s[i] == '/' ||
@@ -22,9 +22,9 @@ String remove_directory_from_path(String const &s) {
 	return substring(s, s.len-len, s.len);
 	return substring(s, s.len-len, s.len);
 }
 }
 
 
-bool path_is_directory(String path);
+gb_internal bool path_is_directory(String path);
 
 
-String directory_from_path(String const &s) {
+gb_internal String directory_from_path(String const &s) {
 	if (path_is_directory(s)) {
 	if (path_is_directory(s)) {
 		return s;
 		return s;
 	}
 	}
@@ -43,7 +43,7 @@ String directory_from_path(String const &s) {
 }
 }
 
 
 #if defined(GB_SYSTEM_WINDOWS)
 #if defined(GB_SYSTEM_WINDOWS)
-	bool path_is_directory(String path) {
+	gb_internal bool path_is_directory(String path) {
 		gbAllocator a = heap_allocator();
 		gbAllocator a = heap_allocator();
 		String16 wstr = string_to_string16(a, path);
 		String16 wstr = string_to_string16(a, path);
 		defer (gb_free(a, wstr.text));
 		defer (gb_free(a, wstr.text));
@@ -55,7 +55,7 @@ String directory_from_path(String const &s) {
 	}
 	}
 
 
 #else
 #else
-	bool path_is_directory(String path) {
+	gb_internal bool path_is_directory(String path) {
 		gbAllocator a = heap_allocator();
 		gbAllocator a = heap_allocator();
 		char *copy = cast(char *)copy_string(a, path).text;
 		char *copy = cast(char *)copy_string(a, path).text;
 		defer (gb_free(a, copy));
 		defer (gb_free(a, copy));
@@ -69,7 +69,7 @@ String directory_from_path(String const &s) {
 #endif
 #endif
 
 
 
 
-String path_to_full_path(gbAllocator a, String path) {
+gb_internal String path_to_full_path(gbAllocator a, String path) {
 	gbAllocator ha = heap_allocator();
 	gbAllocator ha = heap_allocator();
 	char *path_c = gb_alloc_str_len(ha, cast(char *)path.text, path.len);
 	char *path_c = gb_alloc_str_len(ha, cast(char *)path.text, path.len);
 	defer (gb_free(ha, path_c));
 	defer (gb_free(ha, path_c));
@@ -93,7 +93,7 @@ struct Path {
 };
 };
 
 
 // NOTE(Jeroen): Naively turns a Path into a string.
 // NOTE(Jeroen): Naively turns a Path into a string.
-String path_to_string(gbAllocator a, Path path) {
+gb_internal String path_to_string(gbAllocator a, Path path) {
 	if (path.basename.len + path.name.len + path.ext.len == 0) {
 	if (path.basename.len + path.name.len + path.ext.len == 0) {
 		return make_string(nullptr, 0);
 		return make_string(nullptr, 0);
 	}
 	}
@@ -121,7 +121,7 @@ String path_to_string(gbAllocator a, Path path) {
 }
 }
 
 
 // NOTE(Jeroen): Naively turns a Path into a string, then normalizes it using `path_to_full_path`.
 // NOTE(Jeroen): Naively turns a Path into a string, then normalizes it using `path_to_full_path`.
-String path_to_full_path(gbAllocator a, Path path) {
+gb_internal String path_to_full_path(gbAllocator a, Path path) {
 	String temp = path_to_string(heap_allocator(), path);
 	String temp = path_to_string(heap_allocator(), path);
 	defer (gb_free(heap_allocator(), temp.text));
 	defer (gb_free(heap_allocator(), temp.text));
 
 
@@ -130,7 +130,7 @@ String path_to_full_path(gbAllocator a, Path path) {
 
 
 // NOTE(Jeroen): Takes a path like "odin" or "W:\Odin", turns it into a full path,
 // NOTE(Jeroen): Takes a path like "odin" or "W:\Odin", turns it into a full path,
 // and then breaks it into its components to make a Path.
 // and then breaks it into its components to make a Path.
-Path path_from_string(gbAllocator a, String const &path) {
+gb_internal Path path_from_string(gbAllocator a, String const &path) {
 	Path res = {};
 	Path res = {};
 
 
 	if (path.len == 0) return res;
 	if (path.len == 0) return res;
@@ -161,7 +161,7 @@ Path path_from_string(gbAllocator a, String const &path) {
 }
 }
 
 
 // NOTE(Jeroen): Takes a path String and returns the last path element.
 // NOTE(Jeroen): Takes a path String and returns the last path element.
-String last_path_element(String const &path) {
+gb_internal String last_path_element(String const &path) {
 	isize count = 0;
 	isize count = 0;
 	u8 * start = (u8 *)(&path.text[path.len - 1]);
 	u8 * start = (u8 *)(&path.text[path.len - 1]);
 	for (isize length = path.len; length > 0 && path.text[length - 1] != '/'; length--) {
 	for (isize length = path.len; length > 0 && path.text[length - 1] != '/'; length--) {
@@ -177,7 +177,7 @@ String last_path_element(String const &path) {
 	return STR_LIT("");
 	return STR_LIT("");
 }
 }
 
 
-bool path_is_directory(Path path) {
+gb_internal bool path_is_directory(Path path) {
 	String path_string = path_to_full_path(heap_allocator(), path);
 	String path_string = path_to_full_path(heap_allocator(), path);
 	defer (gb_free(heap_allocator(), path_string.text));
 	defer (gb_free(heap_allocator(), path_string.text));
 
 
@@ -204,7 +204,7 @@ enum ReadDirectoryError {
 	ReadDirectory_COUNT,
 	ReadDirectory_COUNT,
 };
 };
 
 
-i64 get_file_size(String path) {
+gb_internal i64 get_file_size(String path) {
 	char *c_str = alloc_cstring(heap_allocator(), path);
 	char *c_str = alloc_cstring(heap_allocator(), path);
 	defer (gb_free(heap_allocator(), c_str));
 	defer (gb_free(heap_allocator(), c_str));
 
 
@@ -219,7 +219,7 @@ i64 get_file_size(String path) {
 
 
 
 
 #if defined(GB_SYSTEM_WINDOWS)
 #if defined(GB_SYSTEM_WINDOWS)
-ReadDirectoryError read_directory(String path, Array<FileInfo> *fi) {
+gb_internal ReadDirectoryError read_directory(String path, Array<FileInfo> *fi) {
 	GB_ASSERT(fi != nullptr);
 	GB_ASSERT(fi != nullptr);
 
 
 	gbAllocator a = heap_allocator();
 	gbAllocator a = heap_allocator();
@@ -314,7 +314,7 @@ ReadDirectoryError read_directory(String path, Array<FileInfo> *fi) {
 
 
 #include <dirent.h>
 #include <dirent.h>
 
 
-ReadDirectoryError read_directory(String path, Array<FileInfo> *fi) {
+gb_internal ReadDirectoryError read_directory(String path, Array<FileInfo> *fi) {
 	GB_ASSERT(fi != nullptr);
 	GB_ASSERT(fi != nullptr);
 
 
 	gbAllocator a = heap_allocator();
 	gbAllocator a = heap_allocator();

+ 7 - 7
src/priority_queue.cpp

@@ -7,7 +7,7 @@ struct PriorityQueue {
 };
 };
 
 
 template <typename T>
 template <typename T>
-bool priority_queue_shift_down(PriorityQueue<T> *pq, isize i0, isize n) {
+gb_internal bool priority_queue_shift_down(PriorityQueue<T> *pq, isize i0, isize n) {
 	// O(n log n)
 	// O(n log n)
 	isize i = i0;
 	isize i = i0;
 	isize j, j1, j2;
 	isize j, j1, j2;
@@ -29,7 +29,7 @@ bool priority_queue_shift_down(PriorityQueue<T> *pq, isize i0, isize n) {
 }
 }
 
 
 template <typename T>
 template <typename T>
-void priority_queue_shift_up(PriorityQueue<T> *pq, isize j) {
+gb_internal void priority_queue_shift_up(PriorityQueue<T> *pq, isize j) {
 	while (0 <= j && j < pq->queue.count) {
 	while (0 <= j && j < pq->queue.count) {
 		isize i = (j-1)/2;
 		isize i = (j-1)/2;
 		if (i == j || pq->cmp(&pq->queue[0], j, i) >= 0) {
 		if (i == j || pq->cmp(&pq->queue[0], j, i) >= 0) {
@@ -43,20 +43,20 @@ void priority_queue_shift_up(PriorityQueue<T> *pq, isize j) {
 // NOTE(bill): When an element at index `i0` has changed its value, this will fix the
 // NOTE(bill): When an element at index `i0` has changed its value, this will fix the
 // the heap ordering. This using a basic "heapsort" with shift up and a shift down parts.
 // the heap ordering. This using a basic "heapsort" with shift up and a shift down parts.
 template <typename T>
 template <typename T>
-void priority_queue_fix(PriorityQueue<T> *pq, isize i) {
+gb_internal void priority_queue_fix(PriorityQueue<T> *pq, isize i) {
 	if (!priority_queue_shift_down(pq, i, pq->queue.count)) {
 	if (!priority_queue_shift_down(pq, i, pq->queue.count)) {
 		priority_queue_shift_up(pq, i);
 		priority_queue_shift_up(pq, i);
 	}
 	}
 }
 }
 
 
 template <typename T>
 template <typename T>
-void priority_queue_push(PriorityQueue<T> *pq, T const &value) {
+gb_internal void priority_queue_push(PriorityQueue<T> *pq, T const &value) {
 	array_add(&pq->queue, value);
 	array_add(&pq->queue, value);
 	priority_queue_shift_up(pq, pq->queue.count-1);
 	priority_queue_shift_up(pq, pq->queue.count-1);
 }
 }
 
 
 template <typename T>
 template <typename T>
-T priority_queue_pop(PriorityQueue<T> *pq) {
+gb_internal T priority_queue_pop(PriorityQueue<T> *pq) {
 	GB_ASSERT(pq->queue.count > 0);
 	GB_ASSERT(pq->queue.count > 0);
 
 
 	isize n = pq->queue.count - 1;
 	isize n = pq->queue.count - 1;
@@ -67,7 +67,7 @@ T priority_queue_pop(PriorityQueue<T> *pq) {
 
 
 
 
 template <typename T>
 template <typename T>
-T priority_queue_remove(PriorityQueue<T> *pq, isize i) {
+gb_internal T priority_queue_remove(PriorityQueue<T> *pq, isize i) {
 	GB_ASSERT(0 <= i && i < pq->queue.count);
 	GB_ASSERT(0 <= i && i < pq->queue.count);
 	isize n = pq->queue.count - 1;
 	isize n = pq->queue.count - 1;
 	if (n != i) {
 	if (n != i) {
@@ -80,7 +80,7 @@ T priority_queue_remove(PriorityQueue<T> *pq, isize i) {
 
 
 
 
 template <typename T>
 template <typename T>
-PriorityQueue<T> priority_queue_create(Array<T> queue,
+gb_internal PriorityQueue<T> priority_queue_create(Array<T> queue,
                                        int  (* cmp) (T *q, isize i, isize j),
                                        int  (* cmp) (T *q, isize i, isize j),
                                        void (* swap)(T *q, isize i, isize j)) {
                                        void (* swap)(T *q, isize i, isize j)) {
 	PriorityQueue<T> pq = {};
 	PriorityQueue<T> pq = {};

+ 59 - 38
src/ptr_map.cpp

@@ -26,7 +26,7 @@ struct PtrMap {
 };
 };
 
 
 
 
-u32 ptr_map_hash_key(uintptr key) {
+gb_internal gb_inline u32 ptr_map_hash_key(uintptr key) {
 #if defined(GB_ARCH_64_BIT)
 #if defined(GB_ARCH_64_BIT)
 	key = (~key) + (key << 21);
 	key = (~key) + (key << 21);
 	key = key ^ (key >> 24);
 	key = key ^ (key >> 24);
@@ -41,35 +41,35 @@ u32 ptr_map_hash_key(uintptr key) {
 	return (word >> 22u) ^ word;
 	return (word >> 22u) ^ word;
 #endif
 #endif
 }
 }
-u32 ptr_map_hash_key(void const *key) {
+gb_internal gb_inline u32 ptr_map_hash_key(void const *key) {
 	return ptr_map_hash_key((uintptr)key);
 	return ptr_map_hash_key((uintptr)key);
 }
 }
 
 
 
 
-template <typename K, typename V> void map_init             (PtrMap<K, V> *h, gbAllocator a, isize capacity = 16);
-template <typename K, typename V> void map_destroy          (PtrMap<K, V> *h);
-template <typename K, typename V> V *  map_get              (PtrMap<K, V> *h, K key);
-template <typename K, typename V> void map_set              (PtrMap<K, V> *h, K key, V const &value);
-template <typename K, typename V> void map_remove           (PtrMap<K, V> *h, K key);
-template <typename K, typename V> void map_clear            (PtrMap<K, V> *h);
-template <typename K, typename V> void map_grow             (PtrMap<K, V> *h);
-template <typename K, typename V> void map_rehash           (PtrMap<K, V> *h, isize new_count);
-template <typename K, typename V> void map_reserve          (PtrMap<K, V> *h, isize cap);
+template <typename K, typename V> gb_internal void map_init             (PtrMap<K, V> *h, gbAllocator a, isize capacity = 16);
+template <typename K, typename V> gb_internal void map_destroy          (PtrMap<K, V> *h);
+template <typename K, typename V> gb_internal V *  map_get              (PtrMap<K, V> *h, K key);
+template <typename K, typename V> gb_internal void map_set              (PtrMap<K, V> *h, K key, V const &value);
+template <typename K, typename V> gb_internal void map_remove           (PtrMap<K, V> *h, K key);
+template <typename K, typename V> gb_internal void map_clear            (PtrMap<K, V> *h);
+template <typename K, typename V> gb_internal void map_grow             (PtrMap<K, V> *h);
+template <typename K, typename V> gb_internal void map_rehash           (PtrMap<K, V> *h, isize new_count);
+template <typename K, typename V> gb_internal void map_reserve          (PtrMap<K, V> *h, isize cap);
 
 
 #if PTR_MAP_ENABLE_MULTI_MAP
 #if PTR_MAP_ENABLE_MULTI_MAP
 // Mutlivalued map procedure
 // Mutlivalued map procedure
-template <typename K, typename V> PtrMapEntry<K, V> * multi_map_find_first(PtrMap<K, V> *h, K key);
-template <typename K, typename V> PtrMapEntry<K, V> * multi_map_find_next (PtrMap<K, V> *h, PtrMapEntry<K, V> *e);
-
-template <typename K, typename V> isize multi_map_count     (PtrMap<K, V> *h, K key);
-template <typename K, typename V> void  multi_map_get_all   (PtrMap<K, V> *h, K key, V *items);
-template <typename K, typename V> void  multi_map_insert    (PtrMap<K, V> *h, K key, V const &value);
-template <typename K, typename V> void  multi_map_remove    (PtrMap<K, V> *h, K key, PtrMapEntry<K, V> *e);
-template <typename K, typename V> void  multi_map_remove_all(PtrMap<K, V> *h, K key);
+template <typename K, typename V> gb_internal PtrMapEntry<K, V> * multi_map_find_first(PtrMap<K, V> *h, K key);
+template <typename K, typename V> gb_internal PtrMapEntry<K, V> * multi_map_find_next (PtrMap<K, V> *h, PtrMapEntry<K, V> *e);
+
+template <typename K, typename V> gb_internal isize multi_map_count     (PtrMap<K, V> *h, K key);
+template <typename K, typename V> gb_internal void  multi_map_get_all   (PtrMap<K, V> *h, K key, V *items);
+template <typename K, typename V> gb_internal void  multi_map_insert    (PtrMap<K, V> *h, K key, V const &value);
+template <typename K, typename V> gb_internal void  multi_map_remove    (PtrMap<K, V> *h, K key, PtrMapEntry<K, V> *e);
+template <typename K, typename V> gb_internal void  multi_map_remove_all(PtrMap<K, V> *h, K key);
 #endif
 #endif
 
 
 template <typename K, typename V>
 template <typename K, typename V>
-gb_inline void map_init(PtrMap<K, V> *h, gbAllocator a, isize capacity) {
+gb_internal gb_inline void map_init(PtrMap<K, V> *h, gbAllocator a, isize capacity) {
 	capacity = next_pow2_isize(capacity);
 	capacity = next_pow2_isize(capacity);
 	slice_init(&h->hashes,  a, capacity);
 	slice_init(&h->hashes,  a, capacity);
 	array_init(&h->entries, a, 0, capacity);
 	array_init(&h->entries, a, 0, capacity);
@@ -79,7 +79,7 @@ gb_inline void map_init(PtrMap<K, V> *h, gbAllocator a, isize capacity) {
 }
 }
 
 
 template <typename K, typename V>
 template <typename K, typename V>
-gb_inline void map_destroy(PtrMap<K, V> *h) {
+gb_internal gb_inline void map_destroy(PtrMap<K, V> *h) {
 	slice_free(&h->hashes, h->entries.allocator);
 	slice_free(&h->hashes, h->entries.allocator);
 	array_free(&h->entries);
 	array_free(&h->entries);
 }
 }
@@ -137,13 +137,13 @@ gb_internal b32 map__full(PtrMap<K, V> *h) {
 }
 }
 
 
 template <typename K, typename V>
 template <typename K, typename V>
-gb_inline void map_grow(PtrMap<K, V> *h) {
+gb_internal gb_inline void map_grow(PtrMap<K, V> *h) {
 	isize new_count = gb_max(h->hashes.count<<1, 16);
 	isize new_count = gb_max(h->hashes.count<<1, 16);
 	map_rehash(h, new_count);
 	map_rehash(h, new_count);
 }
 }
 
 
 template <typename K, typename V>
 template <typename K, typename V>
-void map_reset_entries(PtrMap<K, V> *h) {
+gb_internal void map_reset_entries(PtrMap<K, V> *h) {
 	for (isize i = 0; i < h->hashes.count; i++) {
 	for (isize i = 0; i < h->hashes.count; i++) {
 		h->hashes.data[i] = MAP_SENTINEL;
 		h->hashes.data[i] = MAP_SENTINEL;
 	}
 	}
@@ -161,7 +161,7 @@ void map_reset_entries(PtrMap<K, V> *h) {
 }
 }
 
 
 template <typename K, typename V>
 template <typename K, typename V>
-void map_reserve(PtrMap<K, V> *h, isize cap) {
+gb_internal void map_reserve(PtrMap<K, V> *h, isize cap) {
 	array_reserve(&h->entries, cap);
 	array_reserve(&h->entries, cap);
 	if (h->entries.count*2 < h->hashes.count) {
 	if (h->entries.count*2 < h->hashes.count) {
 		return;
 		return;
@@ -172,12 +172,12 @@ void map_reserve(PtrMap<K, V> *h, isize cap) {
 
 
 
 
 template <typename K, typename V>
 template <typename K, typename V>
-void map_rehash(PtrMap<K, V> *h, isize new_count) {
+gb_internal void map_rehash(PtrMap<K, V> *h, isize new_count) {
 	map_reserve(h, new_count);
 	map_reserve(h, new_count);
 }
 }
 
 
 template <typename K, typename V>
 template <typename K, typename V>
-V *map_get(PtrMap<K, V> *h, K key) {
+gb_internal V *map_get(PtrMap<K, V> *h, K key) {
 	MapIndex index = map__find(h, key).entry_index;
 	MapIndex index = map__find(h, key).entry_index;
 	if (index != MAP_SENTINEL) {
 	if (index != MAP_SENTINEL) {
 		return &h->entries.data[index].value;
 		return &h->entries.data[index].value;
@@ -186,14 +186,14 @@ V *map_get(PtrMap<K, V> *h, K key) {
 }
 }
 
 
 template <typename K, typename V>
 template <typename K, typename V>
-V &map_must_get(PtrMap<K, V> *h, K key) {
+gb_internal V &map_must_get(PtrMap<K, V> *h, K key) {
 	MapIndex index = map__find(h, key).entry_index;
 	MapIndex index = map__find(h, key).entry_index;
 	GB_ASSERT(index != MAP_SENTINEL);
 	GB_ASSERT(index != MAP_SENTINEL);
 	return h->entries.data[index].value;
 	return h->entries.data[index].value;
 }
 }
 
 
 template <typename K, typename V>
 template <typename K, typename V>
-void map_set(PtrMap<K, V> *h, K key, V const &value) {
+gb_internal void map_set(PtrMap<K, V> *h, K key, V const &value) {
 	MapIndex index;
 	MapIndex index;
 	MapFindResult fr;
 	MapFindResult fr;
 	if (h->hashes.count == 0) {
 	if (h->hashes.count == 0) {
@@ -219,7 +219,7 @@ void map_set(PtrMap<K, V> *h, K key, V const &value) {
 
 
 
 
 template <typename K, typename V>
 template <typename K, typename V>
-void map__erase(PtrMap<K, V> *h, MapFindResult const &fr) {
+gb_internal void map__erase(PtrMap<K, V> *h, MapFindResult const &fr) {
 	MapFindResult last;
 	MapFindResult last;
 	if (fr.entry_prev == MAP_SENTINEL) {
 	if (fr.entry_prev == MAP_SENTINEL) {
 		h->hashes.data[fr.hash_index] = h->entries.data[fr.entry_index].next;
 		h->hashes.data[fr.hash_index] = h->entries.data[fr.entry_index].next;
@@ -242,7 +242,7 @@ void map__erase(PtrMap<K, V> *h, MapFindResult const &fr) {
 }
 }
 
 
 template <typename K, typename V>
 template <typename K, typename V>
-void map_remove(PtrMap<K, V> *h, K key) {
+gb_internal void map_remove(PtrMap<K, V> *h, K key) {
 	MapFindResult fr = map__find(h, key);
 	MapFindResult fr = map__find(h, key);
 	if (fr.entry_index != MAP_SENTINEL) {
 	if (fr.entry_index != MAP_SENTINEL) {
 		map__erase(h, fr);
 		map__erase(h, fr);
@@ -250,7 +250,7 @@ void map_remove(PtrMap<K, V> *h, K key) {
 }
 }
 
 
 template <typename K, typename V>
 template <typename K, typename V>
-gb_inline void map_clear(PtrMap<K, V> *h) {
+gb_internal gb_inline void map_clear(PtrMap<K, V> *h) {
 	array_clear(&h->entries);
 	array_clear(&h->entries);
 	for (isize i = 0; i < h->hashes.count; i++) {
 	for (isize i = 0; i < h->hashes.count; i++) {
 		h->hashes.data[i] = MAP_SENTINEL;
 		h->hashes.data[i] = MAP_SENTINEL;
@@ -260,7 +260,7 @@ gb_inline void map_clear(PtrMap<K, V> *h) {
 
 
 #if PTR_MAP_ENABLE_MULTI_MAP
 #if PTR_MAP_ENABLE_MULTI_MAP
 template <typename K, typename V>
 template <typename K, typename V>
-PtrMapEntry<K, V> *multi_map_find_first(PtrMap<K, V> *h, K key) {
+gb_internal PtrMapEntry<K, V> *multi_map_find_first(PtrMap<K, V> *h, K key) {
 	MapIndex i = map__find(h, key).entry_index;
 	MapIndex i = map__find(h, key).entry_index;
 	if (i == MAP_SENTINEL) {
 	if (i == MAP_SENTINEL) {
 		return nullptr;
 		return nullptr;
@@ -269,7 +269,7 @@ PtrMapEntry<K, V> *multi_map_find_first(PtrMap<K, V> *h, K key) {
 }
 }
 
 
 template <typename K, typename V>
 template <typename K, typename V>
-PtrMapEntry<K, V> *multi_map_find_next(PtrMap<K, V> *h, PtrMapEntry<K, V> *e) {
+gb_internal PtrMapEntry<K, V> *multi_map_find_next(PtrMap<K, V> *h, PtrMapEntry<K, V> *e) {
 	MapIndex i = e->next;
 	MapIndex i = e->next;
 	while (i != MAP_SENTINEL) {
 	while (i != MAP_SENTINEL) {
 		if (h->entries.data[i].key == e->key) {
 		if (h->entries.data[i].key == e->key) {
@@ -281,7 +281,7 @@ PtrMapEntry<K, V> *multi_map_find_next(PtrMap<K, V> *h, PtrMapEntry<K, V> *e) {
 }
 }
 
 
 template <typename K, typename V>
 template <typename K, typename V>
-isize multi_map_count(PtrMap<K, V> *h, K key) {
+gb_internal isize multi_map_count(PtrMap<K, V> *h, K key) {
 	isize count = 0;
 	isize count = 0;
 	PtrMapEntry<K, V> *e = multi_map_find_first(h, key);
 	PtrMapEntry<K, V> *e = multi_map_find_first(h, key);
 	while (e != nullptr) {
 	while (e != nullptr) {
@@ -292,7 +292,7 @@ isize multi_map_count(PtrMap<K, V> *h, K key) {
 }
 }
 
 
 template <typename K, typename V>
 template <typename K, typename V>
-void multi_map_get_all(PtrMap<K, V> *h, K key, V *items) {
+gb_internal void multi_map_get_all(PtrMap<K, V> *h, K key, V *items) {
 	isize i = 0;
 	isize i = 0;
 	PtrMapEntry<K, V> *e = multi_map_find_first(h, key);
 	PtrMapEntry<K, V> *e = multi_map_find_first(h, key);
 	while (e != nullptr) {
 	while (e != nullptr) {
@@ -302,7 +302,7 @@ void multi_map_get_all(PtrMap<K, V> *h, K key, V *items) {
 }
 }
 
 
 template <typename K, typename V>
 template <typename K, typename V>
-void multi_map_insert(PtrMap<K, V> *h, K key, V const &value) {
+gb_internal void multi_map_insert(PtrMap<K, V> *h, K key, V const &value) {
 	MapFindResult fr;
 	MapFindResult fr;
 	MapIndex i;
 	MapIndex i;
 	if (h->hashes.count == 0) {
 	if (h->hashes.count == 0) {
@@ -325,7 +325,7 @@ void multi_map_insert(PtrMap<K, V> *h, K key, V const &value) {
 }
 }
 
 
 template <typename K, typename V>
 template <typename K, typename V>
-void multi_map_remove(PtrMap<K, V> *h, K key, PtrMapEntry<K, V> *e) {
+gb_internal void multi_map_remove(PtrMap<K, V> *h, K key, PtrMapEntry<K, V> *e) {
 	MapFindResult fr = map__find_from_entry(h, e);
 	MapFindResult fr = map__find_from_entry(h, e);
 	if (fr.entry_index != MAP_SENTINEL) {
 	if (fr.entry_index != MAP_SENTINEL) {
 		map__erase(h, fr);
 		map__erase(h, fr);
@@ -333,9 +333,30 @@ void multi_map_remove(PtrMap<K, V> *h, K key, PtrMapEntry<K, V> *e) {
 }
 }
 
 
 template <typename K, typename V>
 template <typename K, typename V>
-void multi_map_remove_all(PtrMap<K, V> *h, K key) {
+gb_internal void multi_map_remove_all(PtrMap<K, V> *h, K key) {
 	while (map_get(h, key) != nullptr) {
 	while (map_get(h, key) != nullptr) {
 		map_remove(h, key);
 		map_remove(h, key);
 	}
 	}
 }
 }
 #endif
 #endif
+
+
+template <typename K, typename V>
+gb_internal PtrMapEntry<K, V> *begin(PtrMap<K, V> &m) {
+	return m.entries.data;
+}
+template <typename K, typename V>
+gb_internal PtrMapEntry<K, V> const *begin(PtrMap<K, V> const &m) {
+	return m.entries.data;
+}
+
+
+template <typename K, typename V>
+gb_internal PtrMapEntry<K, V> *end(PtrMap<K, V> &m) {
+	return m.entries.data + m.entries.count;
+}
+
+template <typename K, typename V>
+gb_internal PtrMapEntry<K, V> const *end(PtrMap<K, V> const &m) {
+	return m.entries.data + m.entries.count;
+}

+ 44 - 23
src/ptr_set.cpp

@@ -10,20 +10,20 @@ struct PtrSet {
 	Array<PtrSetEntry<T>> entries;
 	Array<PtrSetEntry<T>> entries;
 };
 };
 
 
-template <typename T> void ptr_set_init   (PtrSet<T> *s, gbAllocator a, isize capacity = 16);
-template <typename T> void ptr_set_destroy(PtrSet<T> *s);
-template <typename T> T    ptr_set_add    (PtrSet<T> *s, T ptr);
-template <typename T> bool ptr_set_update (PtrSet<T> *s, T ptr); // returns true if it previously existed
-template <typename T> bool ptr_set_exists (PtrSet<T> *s, T ptr);
-template <typename T> void ptr_set_remove (PtrSet<T> *s, T ptr);
-template <typename T> void ptr_set_clear  (PtrSet<T> *s);
-template <typename T> void ptr_set_grow   (PtrSet<T> *s);
-template <typename T> void ptr_set_rehash (PtrSet<T> *s, isize new_count);
-template <typename T> void ptr_set_reserve(PtrSet<T> *h, isize cap);
+template <typename T> gb_internal void ptr_set_init   (PtrSet<T> *s, gbAllocator a, isize capacity = 16);
+template <typename T> gb_internal void ptr_set_destroy(PtrSet<T> *s);
+template <typename T> gb_internal T    ptr_set_add    (PtrSet<T> *s, T ptr);
+template <typename T> gb_internal bool ptr_set_update (PtrSet<T> *s, T ptr); // returns true if it previously existed
+template <typename T> gb_internal bool ptr_set_exists (PtrSet<T> *s, T ptr);
+template <typename T> gb_internal void ptr_set_remove (PtrSet<T> *s, T ptr);
+template <typename T> gb_internal void ptr_set_clear  (PtrSet<T> *s);
+template <typename T> gb_internal void ptr_set_grow   (PtrSet<T> *s);
+template <typename T> gb_internal void ptr_set_rehash (PtrSet<T> *s, isize new_count);
+template <typename T> gb_internal void ptr_set_reserve(PtrSet<T> *h, isize cap);
 
 
 
 
 template <typename T>
 template <typename T>
-void ptr_set_init(PtrSet<T> *s, gbAllocator a, isize capacity) {
+gb_internal void ptr_set_init(PtrSet<T> *s, gbAllocator a, isize capacity) {
 	if (capacity != 0) {
 	if (capacity != 0) {
 		capacity = next_pow2_isize(gb_max(16, capacity));
 		capacity = next_pow2_isize(gb_max(16, capacity));
 	}
 	}
@@ -36,7 +36,7 @@ void ptr_set_init(PtrSet<T> *s, gbAllocator a, isize capacity) {
 }
 }
 
 
 template <typename T>
 template <typename T>
-void ptr_set_destroy(PtrSet<T> *s) {
+gb_internal void ptr_set_destroy(PtrSet<T> *s) {
 	slice_free(&s->hashes, s->entries.allocator);
 	slice_free(&s->hashes, s->entries.allocator);
 	array_free(&s->entries);
 	array_free(&s->entries);
 }
 }
@@ -93,13 +93,13 @@ gb_internal bool ptr_set__full(PtrSet<T> *s) {
 }
 }
 
 
 template <typename T>
 template <typename T>
-gb_inline void ptr_set_grow(PtrSet<T> *s) {
+gb_internal gb_inline void ptr_set_grow(PtrSet<T> *s) {
 	isize new_count = gb_max(s->hashes.count<<1, 16);
 	isize new_count = gb_max(s->hashes.count<<1, 16);
 	ptr_set_rehash(s, new_count);
 	ptr_set_rehash(s, new_count);
 }
 }
 
 
 template <typename T>
 template <typename T>
-void ptr_set_reset_entries(PtrSet<T> *s) {
+gb_internal void ptr_set_reset_entries(PtrSet<T> *s) {
 	for (isize i = 0; i < s->hashes.count; i++) {
 	for (isize i = 0; i < s->hashes.count; i++) {
 		s->hashes.data[i] = MAP_SENTINEL;
 		s->hashes.data[i] = MAP_SENTINEL;
 	}
 	}
@@ -117,7 +117,7 @@ void ptr_set_reset_entries(PtrSet<T> *s) {
 }
 }
 
 
 template <typename T>
 template <typename T>
-void ptr_set_reserve(PtrSet<T> *s, isize cap) {
+gb_internal void ptr_set_reserve(PtrSet<T> *s, isize cap) {
 	array_reserve(&s->entries, cap);
 	array_reserve(&s->entries, cap);
 	if (s->entries.count*2 < s->hashes.count) {
 	if (s->entries.count*2 < s->hashes.count) {
 		return;
 		return;
@@ -128,18 +128,18 @@ void ptr_set_reserve(PtrSet<T> *s, isize cap) {
 
 
 
 
 template <typename T>
 template <typename T>
-void ptr_set_rehash(PtrSet<T> *s, isize new_count) {
+gb_internal void ptr_set_rehash(PtrSet<T> *s, isize new_count) {
 	ptr_set_reserve(s, new_count);
 	ptr_set_reserve(s, new_count);
 }
 }
 
 
 template <typename T>
 template <typename T>
-gb_inline bool ptr_set_exists(PtrSet<T> *s, T ptr) {
+gb_internal gb_inline bool ptr_set_exists(PtrSet<T> *s, T ptr) {
 	isize index = ptr_set__find(s, ptr).entry_index;
 	isize index = ptr_set__find(s, ptr).entry_index;
 	return index != MAP_SENTINEL;
 	return index != MAP_SENTINEL;
 }
 }
 
 
 template <typename T>
 template <typename T>
-gb_inline isize ptr_entry_index(PtrSet<T> *s, T ptr) {
+gb_internal gb_inline isize ptr_entry_index(PtrSet<T> *s, T ptr) {
 	isize index = ptr_set__find(s, ptr).entry_index;
 	isize index = ptr_set__find(s, ptr).entry_index;
 	if (index != MAP_SENTINEL) {
 	if (index != MAP_SENTINEL) {
 		return index;
 		return index;
@@ -149,7 +149,7 @@ gb_inline isize ptr_entry_index(PtrSet<T> *s, T ptr) {
 
 
 // Returns true if it already exists
 // Returns true if it already exists
 template <typename T>
 template <typename T>
-T ptr_set_add(PtrSet<T> *s, T ptr) {
+gb_internal T ptr_set_add(PtrSet<T> *s, T ptr) {
 	MapIndex index;
 	MapIndex index;
 	MapFindResult fr;
 	MapFindResult fr;
 	if (s->hashes.count == 0) {
 	if (s->hashes.count == 0) {
@@ -171,7 +171,7 @@ T ptr_set_add(PtrSet<T> *s, T ptr) {
 }
 }
 
 
 template <typename T>
 template <typename T>
-bool ptr_set_update(PtrSet<T> *s, T ptr) { // returns true if it previously existsed
+gb_internal bool ptr_set_update(PtrSet<T> *s, T ptr) { // returns true if it previously existsed
 	bool exists = false;
 	bool exists = false;
 	MapIndex index;
 	MapIndex index;
 	MapFindResult fr;
 	MapFindResult fr;
@@ -198,7 +198,7 @@ bool ptr_set_update(PtrSet<T> *s, T ptr) { // returns true if it previously exis
 
 
 
 
 template <typename T>
 template <typename T>
-void ptr_set__erase(PtrSet<T> *s, MapFindResult fr) {
+gb_internal void ptr_set__erase(PtrSet<T> *s, MapFindResult fr) {
 	MapFindResult last;
 	MapFindResult last;
 	if (fr.entry_prev == MAP_SENTINEL) {
 	if (fr.entry_prev == MAP_SENTINEL) {
 		s->hashes.data[fr.hash_index] = s->entries.data[fr.entry_index].next;
 		s->hashes.data[fr.hash_index] = s->entries.data[fr.entry_index].next;
@@ -219,7 +219,7 @@ void ptr_set__erase(PtrSet<T> *s, MapFindResult fr) {
 }
 }
 
 
 template <typename T>
 template <typename T>
-void ptr_set_remove(PtrSet<T> *s, T ptr) {
+gb_internal void ptr_set_remove(PtrSet<T> *s, T ptr) {
 	MapFindResult fr = ptr_set__find(s, ptr);
 	MapFindResult fr = ptr_set__find(s, ptr);
 	if (fr.entry_index != MAP_SENTINEL) {
 	if (fr.entry_index != MAP_SENTINEL) {
 		ptr_set__erase(s, fr);
 		ptr_set__erase(s, fr);
@@ -227,9 +227,30 @@ void ptr_set_remove(PtrSet<T> *s, T ptr) {
 }
 }
 
 
 template <typename T>
 template <typename T>
-gb_inline void ptr_set_clear(PtrSet<T> *s) {
+gb_internal gb_inline void ptr_set_clear(PtrSet<T> *s) {
 	array_clear(&s->entries);
 	array_clear(&s->entries);
 	for (isize i = 0; i < s->hashes.count; i++) {
 	for (isize i = 0; i < s->hashes.count; i++) {
 		s->hashes.data[i] = MAP_SENTINEL;
 		s->hashes.data[i] = MAP_SENTINEL;
 	}
 	}
 }
 }
+
+
+template <typename T>
+gb_internal PtrSetEntry<T> *begin(PtrSet<T> &m) {
+	return m.entries.data;
+}
+template <typename T>
+gb_internal PtrSetEntry<T> const *begin(PtrSet<T> const &m) {
+	return m.entries.data;
+}
+
+
+template <typename T>
+gb_internal PtrSetEntry<T> *end(PtrSet<T> &m) {
+	return m.entries.data + m.entries.count;
+}
+
+template <typename T>
+gb_internal PtrSetEntry<T> const *end(PtrSet<T> const &m) {
+	return m.entries.data + m.entries.count;
+}

+ 0 - 1030
src/query_data.cpp

@@ -1,1030 +0,0 @@
-struct QueryValue;
-struct QueryValuePair;
-
-gbAllocator query_value_allocator = {};
-
-enum QueryKind {
-	Query_Invalid,
-	Query_String,
-	Query_Boolean,
-	Query_Integer,
-	Query_Float,
-	Query_Array,
-	Query_Map,
-};
-
-struct QueryValuePair {
-	String key;
-	QueryValue *value;
-};
-
-
-struct QueryValue {
-	QueryKind kind;
-	bool packed;
-};
-
-struct QueryValueString : QueryValue {
-	QueryValueString(String const &v) {
-		kind = Query_String;
-		value = v;
-		packed = false;
-	}
-	String value;
-};
-
-struct QueryValueBoolean : QueryValue {
-	QueryValueBoolean(bool v) {
-		kind = Query_Boolean;
-		value = v;
-		packed = false;
-	}
-	bool value;
-};
-
-struct QueryValueInteger : QueryValue {
-	QueryValueInteger(i64 v) {
-		kind = Query_Integer;
-		value = v;
-		packed = false;
-	}
-	i64 value;
-};
-
-struct QueryValueFloat : QueryValue {
-	QueryValueFloat(f64 v) {
-		kind = Query_Float;
-		value = v;
-		packed = false;
-	}
-	f64 value;
-};
-
-struct QueryValueArray : QueryValue {
-	QueryValueArray() {
-		kind = Query_Array;
-		array_init(&value, query_value_allocator);
-		packed = false;
-	}
-	QueryValueArray(Array<QueryValue *> const &v) {
-		kind = Query_Array;
-		value = v;
-		packed = false;
-	}
-	Array<QueryValue *> value;
-
-	void reserve(isize cap) {
-		array_reserve(&value, cap);
-	}
-	void add(QueryValue *v) {
-		array_add(&value, v);
-	}
-	void add(char const *v) {
-		add(make_string_c(cast(char *)v));
-	}
-	void add(String const &v) {
-		auto val = gb_alloc_item(query_value_allocator, QueryValueString);
-		*val = QueryValueString(v);
-		add(val);
-	}
-	void add(bool v) {
-		auto val = gb_alloc_item(query_value_allocator, QueryValueBoolean);
-		*val = QueryValueBoolean(v);
-		add(val);
-	}
-	void add(i64 v) {
-		auto val = gb_alloc_item(query_value_allocator, QueryValueInteger);
-		*val = QueryValueInteger(v);
-		add(val);
-	}
-	void add(f64 v) {
-		auto val = gb_alloc_item(query_value_allocator, QueryValueFloat);
-		*val = QueryValueFloat(v);
-		add(val);
-	}
-};
-
-struct QueryValueMap : QueryValue {
-	QueryValueMap() {
-		kind = Query_Map;
-		array_init(&value, query_value_allocator);
-		packed = false;
-	}
-	QueryValueMap(Array<QueryValuePair> const &v) {
-		kind = Query_Map;
-		value = v;
-		packed = false;
-	}
-	Array<QueryValuePair> value;
-
-
-	void reserve(isize cap) {
-		array_reserve(&value, cap);
-	}
-	void add(char const *k, QueryValue *v) {
-		add(make_string_c(cast(char *)k), v);
-	}
-	void add(String const &k, QueryValue *v) {
-		QueryValuePair kv = {k, v};
-		array_add(&value, kv);
-	}
-
-	void add(char const *k, String const &v) {
-		auto val = gb_alloc_item(query_value_allocator, QueryValueString);
-		*val = QueryValueString(v);
-		add(k, val);
-	}
-	void add(char const *k, char const *v) {
-		add(k, make_string_c(cast(char *)v));
-	}
-	void add(char const *k, bool v) {
-		auto val = gb_alloc_item(query_value_allocator, QueryValueBoolean);
-		*val = QueryValueBoolean(v);
-		add(k, val);
-	}
-	void add(char const *k, i64 v) {
-		auto val = gb_alloc_item(query_value_allocator, QueryValueInteger);
-		*val = QueryValueInteger(v);
-		add(k, val);
-	}
-	void add(char const *k, f64 v) {
-		auto val = gb_alloc_item(query_value_allocator, QueryValueFloat);
-		*val = QueryValueFloat(v);
-		add(k, val);
-	}
-	void add(String const &k, String const &v) {
-		auto val = gb_alloc_item(query_value_allocator, QueryValueString);
-		*val = QueryValueString(v);
-		add(k, val);
-	}
-	void add(String const &k, char const *v) {
-		add(k, make_string_c(cast(char *)v));
-	}
-	void add(String const &k, bool v) {
-		auto val = gb_alloc_item(query_value_allocator, QueryValueBoolean);
-		*val = QueryValueBoolean(v);
-		add(k, val);
-	}
-	void add(String const &k, i64 v) {
-		auto val = gb_alloc_item(query_value_allocator, QueryValueInteger);
-		*val = QueryValueInteger(v);
-		add(k, val);
-	}
-	void add(String const &k, f64 v) {
-		auto val = gb_alloc_item(query_value_allocator, QueryValueFloat);
-		*val = QueryValueFloat(v);
-		add(k, val);
-	}
-};
-
-
-#define DEF_QUERY_PROC(TYPE, VALUETYPE, NAME) TYPE *NAME(VALUETYPE value) { \
-	auto v = gb_alloc_item(query_value_allocator, TYPE); \
-	*v = TYPE(value); \
-	return v; \
-}
-#define DEF_QUERY_PROC0(TYPE, NAME) TYPE *NAME() { \
-	auto v = gb_alloc_item(query_value_allocator, TYPE); \
-	*v = TYPE(); \
-	return v; \
-}
-
-DEF_QUERY_PROC(QueryValueString,  String const &,                query_value_string);
-DEF_QUERY_PROC(QueryValueBoolean, bool,                          query_value_boolean);
-DEF_QUERY_PROC(QueryValueInteger, i64,                           query_value_integer);
-DEF_QUERY_PROC(QueryValueFloat,   f64,                           query_value_float);
-DEF_QUERY_PROC(QueryValueArray,   Array<QueryValue *> const &,   query_value_array);
-DEF_QUERY_PROC(QueryValueMap,     Array<QueryValuePair> const &, query_value_map);
-DEF_QUERY_PROC0(QueryValueArray,  query_value_array);
-DEF_QUERY_PROC0(QueryValueMap,    query_value_map);
-
-isize qprintf(bool format, isize indent, char const *fmt, ...) {
-	if (format) while (indent --> 0) {
-		gb_printf("\t");
-	}
-	va_list va;
-	va_start(va, fmt);
-	isize res = gb_printf_va(fmt, va);
-	va_end(va);
-	return res;
-}
-
-bool qv_valid_char(u8 c) {
-	if (c >= 0x80) {
-		return false;
-	}
-
-	switch (c) {
-	case '\"':
-	case '\n':
-	case '\r':
-	case '\t':
-	case '\v':
-	case '\f':
-		return false;
-	}
-
-	return true;
-}
-
-void print_query_data_as_json(QueryValue *value, bool format = true, isize indent = 0) {
-	if (value == nullptr) {
-		gb_printf("null");
-		return;
-	}
-	switch (value->kind) {
-	case Query_String: {
-		auto v = cast(QueryValueString *)value;
-		String name = v->value;
-		isize extra = 0;
-		for (isize i = 0; i < name.len; i++) {
-			u8 c = name[i];
-			if (!qv_valid_char(c)) {
-				extra += 5;
-			}
-		}
-
-		if (extra == 0) {
-			gb_printf("\"%.*s\"", LIT(name));
-			return;
-		}
-
-		char const hex_table[] = "0123456789ABCDEF";
-		isize buf_len = name.len + extra + 2 + 1;
-
-		u8 *buf = gb_alloc_array(temporary_allocator(), u8, buf_len);
-
-		isize j = 0;
-
-		for (isize i = 0; i < name.len; i++) {
-			u8 c = name[i];
-			if (qv_valid_char(c)) {
-				buf[j+0] = c;
-				j += 1;
-			} else if (c == '"') {
-				buf[j+0] = '\\';
-				buf[j+1] = '\"';
-				j += 2;
-			} else {
-				switch (c) {
-				case '\n': buf[j+0] = '\\'; buf[j+1] = 'n'; j += 2; break;
-				case '\r': buf[j+0] = '\\'; buf[j+1] = 'r'; j += 2; break;
-				case '\t': buf[j+0] = '\\'; buf[j+1] = 't'; j += 2; break;
-				case '\v': buf[j+0] = '\\'; buf[j+1] = 'v'; j += 2; break;
-				case '\f':
-				default:
-					buf[j+0] = '\\';
-					buf[j+1] = hex_table[0];
-					buf[j+2] = hex_table[0];
-					buf[j+3] = hex_table[c >> 4];
-					buf[j+4] = hex_table[c & 0x0f];
-					j += 5;
-					break;
-				}
-			}
-		}
-
-		gb_printf("\"%s\"", buf);
-		return;
-	}
-	case Query_Boolean: {
-		auto v = cast(QueryValueBoolean *)value;
-		if (v->value) {
-			gb_printf("true");
-		} else {
-			gb_printf("false");
-		}
-		return;
-	}
-	case Query_Integer: {
-		auto v = cast(QueryValueInteger *)value;
-		gb_printf("%lld", cast(long long)v->value);
-		return;
-	}
-	case Query_Float: {
-		auto v = cast(QueryValueFloat *)value;
-		gb_printf("%f", v->value);
-		return;
-	}
-	case Query_Array: {
-		auto v = cast(QueryValueArray *)value;
-		if (v->value.count > 0) {
-			bool ff = format && !v->packed;
-			gb_printf("[");
-			if (ff) gb_printf("\n");
-			for_array(i, v->value) {
-				qprintf(ff, indent+1, "");
-				print_query_data_as_json(v->value[i], ff, indent+1);
-				if (i < v->value.count-1) {
-					gb_printf(",");
-					if (!ff && format) {
-						gb_printf(" ");
-					}
-				}
-				if (ff) gb_printf("\n");
-			}
-			qprintf(ff, indent, "]");
-		} else {
-			gb_printf("[]");
-		}
-		return;
-	}
-	case Query_Map: {
-		auto v = cast(QueryValueMap *)value;
-		if (v->value.count > 0) {
-			bool ff = format && !v->packed;
-			gb_printf("{");
-			if (ff) gb_printf("\n");
-			for_array(i, v->value) {
-				auto kv = v->value[i];
-				qprintf(ff, indent+1, "\"%.*s\":", LIT(kv.key));
-				if (format) gb_printf(" ");
-				print_query_data_as_json(kv.value, ff, indent+1);
-				if (i < v->value.count-1) {
-					gb_printf(",");
-					if (!ff && format) {
-						gb_printf(" ");
-					}
-				}
-				if (ff) gb_printf("\n");
-			}
-			qprintf(ff, indent, "}");
-		} else {
-			gb_printf("{}");
-		}
-		return;
-	}
-	}
-}
-
-
-
-int query_data_package_compare(void const *a, void const *b) {
-	AstPackage *x = *cast(AstPackage *const *)a;
-	AstPackage *y = *cast(AstPackage *const *)b;
-
-	if (x == y) {
-		return 0;
-	}
-
-	if (x != nullptr && y != nullptr) {
-		return string_compare(x->name, y->name);
-	} else if (x != nullptr && y == nullptr) {
-		return -1;
-	} else if (x == nullptr && y != nullptr) {
-		return +1;
-	}
-	return 0;
-}
-
-int query_data_definition_compare(void const *a, void const *b) {
-	Entity *x = *cast(Entity *const *)a;
-	Entity *y = *cast(Entity *const *)b;
-
-	if (x == y) {
-		return 0;
-	} else if (x != nullptr && y == nullptr) {
-		return -1;
-	} else if (x == nullptr && y != nullptr) {
-		return +1;
-	}
-
-	if (x->pkg != y->pkg) {
-		i32 res = query_data_package_compare(&x->pkg, &y->pkg);
-		if (res != 0) {
-			return res;
-		}
-	}
-
-	return string_compare(x->token.string, y->token.string);
-}
-
-int entity_name_compare(void const *a, void const *b) {
-	Entity *x = *cast(Entity *const *)a;
-	Entity *y = *cast(Entity *const *)b;
-	if (x == y) {
-		return 0;
-	} else if (x != nullptr && y == nullptr) {
-		return -1;
-	} else if (x == nullptr && y != nullptr) {
-		return +1;
-	}
-	return string_compare(x->token.string, y->token.string);
-}
-
-
-void generate_and_print_query_data_global_definitions(Checker *c, Timings *timings);
-void generate_and_print_query_data_go_to_definitions(Checker *c);
-
-void generate_and_print_query_data(Checker *c, Timings *timings) {
-	query_value_allocator = heap_allocator();
-	switch (build_context.query_data_set_settings.kind) {
-	case QueryDataSet_GlobalDefinitions:
-		generate_and_print_query_data_global_definitions(c, timings);
-		return;
-	case QueryDataSet_GoToDefinitions:
-		generate_and_print_query_data_go_to_definitions(c);
-		return;
-	}
-}
-
-
-void generate_and_print_query_data_global_definitions(Checker *c, Timings *timings) {
-	auto *root = query_value_map();
-
-	if (global_error_collector.errors.count > 0) {
-		auto *errors = query_value_array();
-		root->add("errors", errors);
-		for_array(i, global_error_collector.errors) {
-			String err = string_trim_whitespace(global_error_collector.errors[i]);
-			errors->add(err);
-		}
-
-	}
-
-	{ // Packages
-		auto *packages = query_value_array();
-		root->add("packages", packages);
-
-		auto sorted_packages = array_make<AstPackage *>(query_value_allocator, 0, c->info.packages.entries.count);
-		defer (array_free(&sorted_packages));
-
-		for_array(i, c->info.packages.entries) {
-			AstPackage *pkg = c->info.packages.entries[i].value;
-			if (pkg != nullptr) {
-				array_add(&sorted_packages, pkg);
-			}
-		}
-		gb_sort_array(sorted_packages.data, sorted_packages.count, query_data_package_compare);
-		packages->reserve(sorted_packages.count);
-
-		for_array(i, sorted_packages) {
-			AstPackage *pkg = sorted_packages[i];
-			String name = pkg->name;
-			String fullpath = pkg->fullpath;
-
-			auto *files = query_value_array();
-			files->reserve(pkg->files.count);
-			for_array(j, pkg->files) {
-				AstFile *f = pkg->files[j];
-				files->add(f->fullpath);
-			}
-
-			auto *package = query_value_map();
-			package->reserve(3);
-			packages->add(package);
-
-			package->add("name", pkg->name);
-			package->add("fullpath", pkg->fullpath);
-			package->add("files", files);
-		}
-	}
-
-	if (c->info.definitions.count > 0) {
-		auto *definitions = query_value_array();
-		root->add("definitions", definitions);
-
-		auto sorted_definitions = array_make<Entity *>(query_value_allocator, 0, c->info.definitions.count);
-		defer (array_free(&sorted_definitions));
-
-		for_array(i, c->info.definitions) {
-			Entity *e = c->info.definitions[i];
-			String name = e->token.string;
-			if (is_blank_ident(name)) {
-				continue;
-			}
-			if ((e->scope->flags & (ScopeFlag_Pkg|ScopeFlag_File)) == 0) {
-				continue;
-			}
-			if (e->parent_proc_decl != nullptr) {
-				continue;
-			}
-			switch (e->kind) {
-			case Entity_Builtin:
-			case Entity_Nil:
-			case Entity_Label:
-				continue;
-			}
-			if (e->pkg == nullptr) {
-				continue;
-			}
-			if (e->token.pos.line == 0) {
-				continue;
-			}
-			if (e->kind == Entity_Procedure) {
-				Type *t = base_type(e->type);
-				if (t->kind != Type_Proc) {
-					continue;
-				}
-				if (t->Proc.is_poly_specialized) {
-					continue;
-				}
-			}
-			if (e->kind == Entity_TypeName) {
-				Type *t = base_type(e->type);
-				if (t->kind == Type_Struct) {
-					if (t->Struct.is_poly_specialized) {
-						continue;
-					}
-				}
-				if (t->kind == Type_Union) {
-					if (t->Union.is_poly_specialized) {
-						continue;
-					}
-				}
-			}
-
-			array_add(&sorted_definitions, e);
-		}
-
-		gb_sort_array(sorted_definitions.data, sorted_definitions.count, query_data_definition_compare);
-		definitions->reserve(sorted_definitions.count);
-
-		for_array(i, sorted_definitions) {
-			Entity *e = sorted_definitions[i];
-			String name = e->token.string;
-
-			auto *def = query_value_map();
-			def->reserve(16);
-			definitions->add(def);
-
-			def->add("package",     e->pkg->name);
-			def->add("name",        name);
-			def->add("filepath",    get_file_path_string(e->token.pos.file_id));
-			def->add("line",        cast(i64)e->token.pos.line);
-			def->add("column",      cast(i64)e->token.pos.column);
-			def->add("file_offset", cast(i64)e->token.pos.offset);
-
-			switch (e->kind) {
-			case Entity_Constant:    def->add("kind", str_lit("constant"));        break;
-			case Entity_Variable:    def->add("kind", str_lit("variable"));        break;
-			case Entity_TypeName:    def->add("kind", str_lit("type name"));       break;
-			case Entity_Procedure:   def->add("kind", str_lit("procedure"));       break;
-			case Entity_ProcGroup:   def->add("kind", str_lit("procedure group")); break;
-			case Entity_ImportName:  def->add("kind", str_lit("import name"));     break;
-			case Entity_LibraryName: def->add("kind", str_lit("library name"));    break;
-			default: GB_PANIC("Invalid entity kind to be added");
-			}
-
-
-			if (e->type != nullptr && e->type != t_invalid) {
-				Type *t = e->type;
-				Type *bt = t;
-
-				switch (e->kind) {
-				case Entity_TypeName:
-					if (!e->TypeName.is_type_alias) {
-						bt = base_type(t);
-					}
-					break;
-				}
-
-				{
-					gbString str = type_to_string(t);
-					String type_str = make_string(cast(u8 *)str, gb_string_length(str));
-					def->add("type", type_str);
-				}
-				if (t != bt) {
-					gbString str = type_to_string(bt);
-					String type_str = make_string(cast(u8 *)str, gb_string_length(str));
-					def->add("base_type", type_str);
-				}
-				{
-					String type_kind = {};
-					Type *bt = base_type(t);
-					switch (bt->kind) {
-					case Type_Pointer:      type_kind = str_lit("pointer");       break;
-					case Type_Array:        type_kind = str_lit("array");         break;
-					case Type_Slice:        type_kind = str_lit("slice");         break;
-					case Type_DynamicArray: type_kind = str_lit("dynamic array"); break;
-					case Type_Map:          type_kind = str_lit("map");           break;
-					case Type_Struct:       type_kind = str_lit("struct");        break;
-					case Type_Union:        type_kind = str_lit("union");         break;
-					case Type_Enum:         type_kind = str_lit("enum");          break;
-					case Type_Proc:         type_kind = str_lit("procedure");     break;
-					case Type_BitSet:       type_kind = str_lit("bit set");       break;
-					case Type_SimdVector:   type_kind = str_lit("simd vector");   break;
-
-					case Type_Generic:
-					case Type_Tuple:
-						GB_PANIC("Invalid definition type");
-						break;
-					}
-					if (type_kind.len > 0) {
-						def->add("type_kind", type_kind);
-					}
-				}
-			}
-
-			if (e->kind == Entity_TypeName) {
-				def->add("size",  type_size_of(e->type));
-				def->add("align", type_align_of(e->type));
-
-
-				if (is_type_struct(e->type)) {
-					auto *data = query_value_map();
-					data->reserve(6);
-
-					def->add("data", data);
-
-					Type *t = base_type(e->type);
-					GB_ASSERT(t->kind == Type_Struct);
-
-					if (t->Struct.is_polymorphic) {
-						data->add("polymorphic", cast(bool)t->Struct.is_polymorphic);
-					}
-					if (t->Struct.is_poly_specialized) {
-						data->add("polymorphic_specialized", cast(bool)t->Struct.is_poly_specialized);
-					}
-					if (t->Struct.is_packed) {
-						data->add("packed", cast(bool)t->Struct.is_packed);
-					}
-					if (t->Struct.is_raw_union) {
-						data->add("raw_union", cast(bool)t->Struct.is_raw_union);
-					}
-
-					auto *fields = query_value_array();
-					data->add("fields", fields);
-					fields->reserve(t->Struct.fields.count);
-					fields->packed = true;
-
-					for_array(j, t->Struct.fields) {
-						Entity *e = t->Struct.fields[j];
-						String name = e->token.string;
-						if (is_blank_ident(name)) {
-							continue;
-						}
-
-						fields->add(name);
-					}
-				} else if (is_type_union(e->type)) {
-					auto *data = query_value_map();
-					data->reserve(4);
-
-					def->add("data", data);
-					Type *t = base_type(e->type);
-					GB_ASSERT(t->kind == Type_Union);
-
-					if (t->Union.is_polymorphic) {
-						data->add("polymorphic", cast(bool)t->Union.is_polymorphic);
-					}
-					if (t->Union.is_poly_specialized) {
-						data->add("polymorphic_specialized", cast(bool)t->Union.is_poly_specialized);
-					}
-
-					auto *variants = query_value_array();
-					variants->reserve(t->Union.variants.count);
-					data->add("variants", variants);
-
-					for_array(j, t->Union.variants) {
-						Type *vt = t->Union.variants[j];
-
-						gbString str = type_to_string(vt);
-						String type_str = make_string(cast(u8 *)str, gb_string_length(str));
-						variants->add(type_str);
-					}
-				}
-			}
-
-			if (e->kind == Entity_Procedure) {
-				Type *t = base_type(e->type);
-				GB_ASSERT(t->kind == Type_Proc);
-
-				bool is_polymorphic = t->Proc.is_polymorphic;
-				bool is_poly_specialized = t->Proc.is_poly_specialized;
-				bool ok = is_polymorphic || is_poly_specialized;
-				if (ok) {
-					auto *data = query_value_map();
-					data->reserve(4);
-
-					def->add("data", data);
-					if (is_polymorphic) {
-						data->add("polymorphic", cast(bool)is_polymorphic);
-					}
-					if (is_poly_specialized) {
-						data->add("polymorphic_specialized", cast(bool)is_poly_specialized);
-					}
-				}
-			}
-
-			if (e->kind == Entity_ProcGroup) {
-				auto *procedures = query_value_array();
-				procedures->reserve(e->ProcGroup.entities.count);
-
-				for_array(j, e->ProcGroup.entities) {
-					Entity *p = e->ProcGroup.entities[j];
-
-					auto *procedure = query_value_map();
-					procedure->reserve(2);
-					procedure->packed = true;
-
-					procedures->add(procedure);
-
-					procedure->add("package", p->pkg->name);
-					procedure->add("name",    p->token.string);
-				}
-				def->add("procedures", procedures);
-			}
-
-			DeclInfo *di = e->decl_info;
-			if (di != nullptr) {
-				if (di->is_using) {
-					def->add("using", query_value_boolean(true));
-				}
-			}
-		}
-	}
-
-	if (build_context.show_timings) {
-		Timings *t = timings;
-		timings__stop_current_section(t);
-		t->total.finish = time_stamp_time_now();
-		isize max_len = gb_min(36, t->total.label.len);
-		for_array(i, t->sections) {
-			TimeStamp ts = t->sections[i];
-			max_len = gb_max(max_len, ts.label.len);
-		}
-		t->total_time_seconds = time_stamp_as_s(t->total, t->freq);
-
-		auto *tims = query_value_map();
-		tims->reserve(8);
-		root->add("timings", tims);
-		tims->add("time_unit", str_lit("s"));
-
-		tims->add(t->total.label, cast(f64)t->total_time_seconds);
-
-
-		Parser *p = c->parser;
-		if (p != nullptr) {
-			isize lines    = p->total_line_count;
-			isize tokens   = p->total_token_count;
-			isize files    = 0;
-			isize packages = p->packages.count;
-			isize total_file_size = 0;
-			for_array(i, p->packages) {
-				files += p->packages[i]->files.count;
-				for_array(j, p->packages[i]->files) {
-					AstFile *file = p->packages[i]->files[j];
-					total_file_size += file->tokenizer.end - file->tokenizer.start;
-				}
-			}
-
-			tims->add("total_lines",     cast(i64)lines);
-			tims->add("total_tokens",    cast(i64)tokens);
-			tims->add("total_files",     cast(i64)files);
-			tims->add("total_packages",  cast(i64)packages);
-			tims->add("total_file_size", cast(i64)total_file_size);
-
-			auto *sections = query_value_map();
-			sections->reserve(t->sections.count);
-			tims->add("sections", sections);
-			for_array(i, t->sections) {
-				TimeStamp ts = t->sections[i];
-				f64 section_time = time_stamp_as_s(ts, t->freq);
-
-				auto *section = query_value_map();
-				section->reserve(2);
-				sections->add(ts.label, section);
-				section->add("time", cast(f64)section_time);
-				section->add("total_fraction", cast(f64)(section_time/t->total_time_seconds));
-			}
-		}
-	}
-
-
-	print_query_data_as_json(root, !build_context.query_data_set_settings.compact);
-	gb_printf("\n");
-}
-
-
-
-template <typename T>
-struct BinaryArray {
-	u32 offset; // Offset in bytes from the top of the file
-	u32 length; // Number of elements in array of type T
-};
-
-template <typename T>
-Array<T> binary_array_from_data(BinaryArray<T> ba, void *data) {
-	Array<T> res = {};
-	res.data     = cast(T *)(cast(u8 *)data + ba.offset);
-	res.count    = ba.length;
-	res.capacity = ba.length;
-	return res;
-}
-
-typedef BinaryArray<u8> BinaryString;
-
-struct GoToDefIdent {
-	u64 use_offset;  // offset of identifier use in bytes from the start of the file that contains it
-	u32 len;         // length in bytes of the identifier
-	u32 def_file_id;
-	u64 def_offset;  // offset of entity definition in bytes from the start of the file that contains it
-};
-
-struct GoToDefFile {
-	u32 id;
-	BinaryString path;
-	BinaryArray<GoToDefIdent> idents;
-};
-
-struct GoToDefHeader {
-	u8  magic[4]; // ogtd (odin-go-to-definitions)
-	u32 version;  // 1
-	BinaryArray<GoToDefFile> files;
-};
-
-struct GoToDefFileMap {
-	AstFile *f;
-	u32 id;
-	Array<Ast *> idents;
-};
-
-
-int go_to_def_file_map_compare(void const *a, void const *b) {
-	GoToDefFileMap const *x = cast(GoToDefFileMap const *)a;
-	GoToDefFileMap const *y = cast(GoToDefFileMap const *)b;
-	if (x == y) {
-		return 0;
-	} else if (x != nullptr && y == nullptr) {
-		return -1;
-	} else if (x == nullptr && y != nullptr) {
-		return +1;
-	}
-	if (x->f->id < y->f->id) {
-		return -1;
-	} else if (x->f->id > y->f->id) {
-		return +1;
-	}
-	return 0;
-}
-
-int quick_ident_compare(void const *a, void const *b) {
-	Ast *x = *cast(Ast **)a;
-	Ast *y = *cast(Ast **)b;
-
-	// NOTE(bill): This assumes that the file is same
-	if (x->Ident.token.pos.offset < y->Ident.token.pos.offset) {
-		return -1;
-	} else if (x->Ident.token.pos.offset > y->Ident.token.pos.offset) {
-		return +1;
-	}
-	return 0;
-}
-
-
-void generate_and_print_query_data_go_to_definitions(Checker *c) {
-	GB_ASSERT(c->info.allow_identifier_uses);
-
-	gbAllocator a = query_value_allocator;
-
-	isize file_path_memory_needed = 0;
-	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;
-		file_path_memory_needed += f->fullpath.len+1; // add NUL terminator
-
-
-		GoToDefFileMap x = {};
-		x.f = f;
-		array_init(&x.idents, a);
-		array_add(&files, x);
-	}
-	gb_sort_array(files.data, files.count, go_to_def_file_map_compare);
-
-	auto file_id_map_to_index = array_make<isize>(a, files[files.count-1].f->id + 1);
-	for_array(i, file_id_map_to_index) {
-		file_id_map_to_index[i] = -1;
-	}
-	for_array(i, files) {
-		file_id_map_to_index[files[i].f->id] = i;
-	}
-
-
-
-	for_array(i, c->info.identifier_uses) {
-		Ast *ast = c->info.identifier_uses[i];
-		GB_ASSERT(ast->kind == Ast_Ident);
-		TokenPos pos = ast->Ident.token.pos;
-		Entity *e = ast->Ident.entity;
-		if (e == nullptr) {
-			continue;
-		}
-
-
-		AstFile **use_file_found = string_map_get(&c->info.files, get_file_path_string(pos.file_id));
-		GB_ASSERT(use_file_found != nullptr);
-		AstFile *use_file = *use_file_found;
-		GB_ASSERT(use_file != nullptr);
-
-		if (e->scope == nullptr) {
-			GB_ASSERT(e->flags & EntityFlag_Field);
-			continue;
-		}
-		if (e->scope->flags & ScopeFlag_Global) {
-			continue;
-		}
-
-		isize idx = file_id_map_to_index[use_file->id];
-		if (idx >= 0) {
-			array_add(&files[idx].idents, ast);
-		} else {
-			// TODO(bill): Handle invalid map case?
-		}
-	}
-
-	for_array(i, files) {
-		GoToDefFileMap *f = &files[i];
-		gb_sort_array(f->idents.data, f->idents.count, quick_ident_compare);
-		// gb_printf_err("%lld %.*s -> %lld\n", f->f->id, LIT(f->f->fullpath), f->idents.count);
-	}
-
-
-
-	isize data_min_size = 0;
-
-	u32 header_offset = cast(u32)data_min_size; gb_unused(header_offset);
-	data_min_size += gb_size_of(GoToDefHeader);
-	data_min_size = align_formula_isize(data_min_size, 8);
-
-	u32 file_offset = cast(u32)data_min_size;
-	data_min_size += gb_size_of(GoToDefFile) * files.count;
-	data_min_size = align_formula_isize(data_min_size, 8);
-
-	u32 file_path_offset = cast(u32)data_min_size;
-	data_min_size += file_path_memory_needed;
-	data_min_size = align_formula_isize(data_min_size, 8);
-
-	u32 idents_offset = cast(u32)data_min_size;
-	data_min_size += gb_size_of(GoToDefIdent) * c->info.identifier_uses.count;
-
-
-	auto data = array_make<u8>(a, 0, data_min_size);
-	defer (array_free(&data));
-
-	GoToDefHeader header = {};
-	gb_memmove(header.magic, "ogtd", 4);
-	header.version = 1;
-	header.files.length = cast(u32)files.count;
-	header.files.offset = file_offset;
-
-	array_add_elems(&data, cast(u8 *)&header, gb_size_of(header));
-
-	array_resize(&data, data_min_size);
-
-	auto binary_files = binary_array_from_data(header.files, data.data);
-
-	u32 file_path_offset_index = file_path_offset;
-	u32 idents_offset_index = idents_offset;
-	for_array(i, files) {
-		GoToDefFileMap *f_map = &files[i];
-		AstFile *f = f_map->f;
-		binary_files[i].id = cast(u32)f->id;
-
-		binary_files[i].path.offset = file_path_offset_index;
-		binary_files[i].path.length = cast(u32)f->fullpath.len;
-
-		binary_files[i].idents.offset = idents_offset_index;
-		binary_files[i].idents.length = cast(u32)f_map->idents.count;
-
-		auto path = binary_array_from_data(binary_files[i].path, data.data);
-		gb_memmove(path.data, f->fullpath.text, f->fullpath.len);
-		path.data[f->fullpath.len] = 0;
-
-
-		auto idents = binary_array_from_data(binary_files[i].idents, data.data);
-		for_array(j, f_map->idents) {
-			Ast *ast = f_map->idents[j];
-			GB_ASSERT(ast->kind == Ast_Ident);
-
-			Entity *e = ast->Ident.entity;
-			TokenPos def = e->token.pos;
-			AstFile *def_file = e->file;
-
-			if (def_file == nullptr) {
-				auto *def_file_found = string_map_get(&c->info.files, get_file_path_string(e->token.pos.file_id));
-				if (def_file_found == nullptr) {
-					continue;
-				}
-				def_file = *def_file_found;
-			}
-
-			isize file_index = file_id_map_to_index[def_file->id];
-			GB_ASSERT(file_index >= 0);
-
-			idents[j].use_offset  = cast(u64)ast->Ident.token.pos.offset;
-			idents[j].len         = cast(u32)ast->Ident.token.string.len;
-			idents[j].def_file_id = cast(u32)def_file->id;
-			idents[j].def_offset  = cast(u64)e->token.pos.offset;
-
-			// gb_printf_err("%llu %llu %llu %llu\n", idents[j].len, idents[j].use_offset, idents[j].def_file_id, idents[j].def_offset);
-		}
-
-		file_path_offset_index += cast(u32)(f->fullpath.len + 1);
-		idents_offset_index += cast(u32)(f_map->idents.count * gb_size_of(GoToDefIdent));
-	}
-
-
-	gb_file_write(gb_file_get_standard(gbFileStandard_Output), data.data, data.count*gb_size_of(*data.data));
-}
-

+ 6 - 6
src/queue.cpp

@@ -23,7 +23,7 @@ struct MPMCQueue {
 
 
 
 
 
 
-void mpmc_internal_init_indices(MPMCQueueAtomicIdx *indices, i32 offset, i32 size) {
+gb_internal void mpmc_internal_init_indices(MPMCQueueAtomicIdx *indices, i32 offset, i32 size) {
 	GB_ASSERT(offset % 8 == 0);
 	GB_ASSERT(offset % 8 == 0);
 	GB_ASSERT(size % 8 == 0);
 	GB_ASSERT(size % 8 == 0);
 
 
@@ -43,7 +43,7 @@ void mpmc_internal_init_indices(MPMCQueueAtomicIdx *indices, i32 offset, i32 siz
 
 
 
 
 template <typename T>
 template <typename T>
-void mpmc_init(MPMCQueue<T> *q, gbAllocator a, isize size_i) {
+gb_internal void mpmc_init(MPMCQueue<T> *q, gbAllocator a, isize size_i) {
 	if (size_i < 8) {
 	if (size_i < 8) {
 		size_i = 8;
 		size_i = 8;
 	}
 	}
@@ -64,7 +64,7 @@ void mpmc_init(MPMCQueue<T> *q, gbAllocator a, isize size_i) {
 
 
 
 
 template <typename T>
 template <typename T>
-void mpmc_destroy(MPMCQueue<T> *q) {
+gb_internal void mpmc_destroy(MPMCQueue<T> *q) {
 	mutex_destroy(&q->mutex);
 	mutex_destroy(&q->mutex);
 	gb_free(q->allocator, q->nodes);
 	gb_free(q->allocator, q->nodes);
 	gb_free(q->allocator, q->indices);
 	gb_free(q->allocator, q->indices);
@@ -72,7 +72,7 @@ void mpmc_destroy(MPMCQueue<T> *q) {
 
 
 
 
 template <typename T>
 template <typename T>
-bool mpmc_internal_grow(MPMCQueue<T> *q) {
+gb_internal bool mpmc_internal_grow(MPMCQueue<T> *q) {
 	mutex_lock(&q->mutex);
 	mutex_lock(&q->mutex);
 	i32 old_size = q->mask+1;
 	i32 old_size = q->mask+1;
 	i32 new_size = old_size*2;
 	i32 new_size = old_size*2;
@@ -95,7 +95,7 @@ bool mpmc_internal_grow(MPMCQueue<T> *q) {
 }
 }
 
 
 template <typename T>
 template <typename T>
-i32 mpmc_enqueue(MPMCQueue<T> *q, T const &data) {
+gb_internal i32 mpmc_enqueue(MPMCQueue<T> *q, T const &data) {
 	GB_ASSERT(q->mask != 0);
 	GB_ASSERT(q->mask != 0);
 
 
 	i32 head_idx = q->head_idx.load(std::memory_order_relaxed);
 	i32 head_idx = q->head_idx.load(std::memory_order_relaxed);
@@ -125,7 +125,7 @@ i32 mpmc_enqueue(MPMCQueue<T> *q, T const &data) {
 }
 }
 
 
 template <typename T>
 template <typename T>
-bool mpmc_dequeue(MPMCQueue<T> *q, T *data_) {
+gb_internal bool mpmc_dequeue(MPMCQueue<T> *q, T *data_) {
 	if (q->mask == 0) {
 	if (q->mask == 0) {
 		return false;
 		return false;
 	}
 	}

+ 13 - 13
src/range_cache.cpp

@@ -10,17 +10,17 @@ struct RangeCache {
 };
 };
 
 
 
 
-RangeCache range_cache_make(gbAllocator a) {
+gb_internal RangeCache range_cache_make(gbAllocator a) {
 	RangeCache cache = {};
 	RangeCache cache = {};
 	array_init(&cache.ranges, a);
 	array_init(&cache.ranges, a);
 	return cache;
 	return cache;
 }
 }
 
 
-void range_cache_destroy(RangeCache *c) {
+gb_internal void range_cache_destroy(RangeCache *c) {
 	array_free(&c->ranges);
 	array_free(&c->ranges);
 }
 }
 
 
-bool range_cache_add_index(RangeCache *c, i64 index) {
+gb_internal bool range_cache_add_index(RangeCache *c, i64 index) {
 	for_array(i, c->ranges) {
 	for_array(i, c->ranges) {
 		RangeValue v = c->ranges[i];
 		RangeValue v = c->ranges[i];
 		if (v.lo <= index && index <= v.hi) {
 		if (v.lo <= index && index <= v.hi) {
@@ -33,7 +33,7 @@ bool range_cache_add_index(RangeCache *c, i64 index) {
 }
 }
 
 
 
 
-bool range_cache_add_range(RangeCache *c, i64 lo, i64 hi) {
+gb_internal bool range_cache_add_range(RangeCache *c, i64 lo, i64 hi) {
 	GB_ASSERT(lo <= hi);
 	GB_ASSERT(lo <= hi);
 	for_array(i, c->ranges) {
 	for_array(i, c->ranges) {
 		RangeValue v = c->ranges[i];
 		RangeValue v = c->ranges[i];
@@ -59,12 +59,12 @@ bool range_cache_add_range(RangeCache *c, i64 lo, i64 hi) {
 }
 }
 
 
 
 
-bool range_cache_index_exists(RangeCache *c, i64 index) {
-	for_array(i, c->ranges) {
-		RangeValue v = c->ranges[i];
-		if (v.lo <= index && index <= v.hi) {
-			return true;
-		}
-	}
-	return false;
-}
+// gb_internal bool range_cache_index_exists(RangeCache *c, i64 index) {
+// 	for_array(i, c->ranges) {
+// 		RangeValue v = c->ranges[i];
+// 		if (v.lo <= index && index <= v.hi) {
+// 			return true;
+// 		}
+// 	}
+// 	return false;
+// }

+ 60 - 74
src/string.cpp

@@ -1,6 +1,6 @@
 gb_global BlockingMutex string_buffer_mutex = {};
 gb_global BlockingMutex string_buffer_mutex = {};
 
 
-void init_string_buffer_memory(void) {
+gb_internal void init_string_buffer_memory(void) {
 	mutex_init(&string_buffer_mutex);
 	mutex_init(&string_buffer_mutex);
 }
 }
 
 
@@ -36,7 +36,7 @@ struct String16 {
 };
 };
 
 
 
 
-gb_inline String make_string(u8 const *text, isize len) {
+gb_internal gb_inline String make_string(u8 const *text, isize len) {
 	String s;
 	String s;
 	s.text = cast(u8 *)text;
 	s.text = cast(u8 *)text;
 	if (len < 0) {
 	if (len < 0) {
@@ -47,14 +47,14 @@ gb_inline String make_string(u8 const *text, isize len) {
 }
 }
 
 
 
 
-gb_inline String16 make_string16(wchar_t const *text, isize len) {
+gb_internal gb_inline String16 make_string16(wchar_t const *text, isize len) {
 	String16 s;
 	String16 s;
 	s.text = cast(wchar_t *)text;
 	s.text = cast(wchar_t *)text;
 	s.len = len;
 	s.len = len;
 	return s;
 	return s;
 }
 }
 
 
-isize string16_len(wchar_t const *s) {
+gb_internal isize string16_len(wchar_t const *s) {
 	if (s == nullptr) {
 	if (s == nullptr) {
 		return 0;
 		return 0;
 	}
 	}
@@ -66,15 +66,15 @@ isize string16_len(wchar_t const *s) {
 }
 }
 
 
 
 
-gb_inline String make_string_c(char const *text) {
+gb_internal gb_inline String make_string_c(char const *text) {
 	return make_string(cast(u8 *)cast(void *)text, gb_strlen(text));
 	return make_string(cast(u8 *)cast(void *)text, gb_strlen(text));
 }
 }
 
 
-gb_inline String16 make_string16_c(wchar_t const *text) {
+gb_internal gb_inline String16 make_string16_c(wchar_t const *text) {
 	return make_string16(text, string16_len(text));
 	return make_string16(text, string16_len(text));
 }
 }
 
 
-String substring(String const &s, isize lo, isize hi) {
+gb_internal String substring(String const &s, isize lo, isize hi) {
 	isize max = s.len;
 	isize max = s.len;
 	GB_ASSERT_MSG(lo <= hi && hi <= max, "%td..%td..%td", lo, hi, max);
 	GB_ASSERT_MSG(lo <= hi && hi <= max, "%td..%td..%td", lo, hi, max);
 
 
@@ -82,24 +82,16 @@ String substring(String const &s, isize lo, isize hi) {
 }
 }
 
 
 
 
-char *alloc_cstring(gbAllocator a, String s) {
+gb_internal char *alloc_cstring(gbAllocator a, String s) {
 	char *c_str = gb_alloc_array(a, char, s.len+1);
 	char *c_str = gb_alloc_array(a, char, s.len+1);
 	gb_memmove(c_str, s.text, s.len);
 	gb_memmove(c_str, s.text, s.len);
 	c_str[s.len] = '\0';
 	c_str[s.len] = '\0';
 	return c_str;
 	return c_str;
 }
 }
 
 
-char *cstring_duplicate(gbAllocator a, char const *s) {
-	isize len = gb_strlen(s);
-	char *c_str = gb_alloc_array(a, char, len+1);
-	gb_memmove(c_str, s, len);
-	c_str[len] = '\0';
-	return c_str;
-}
-
 
 
 
 
-gb_inline bool str_eq_ignore_case(String const &a, String const &b) {
+gb_internal gb_inline bool str_eq_ignore_case(String const &a, String const &b) {
 	if (a.len == b.len) {
 	if (a.len == b.len) {
 		for (isize i = 0; i < a.len; i++) {
 		for (isize i = 0; i < a.len; i++) {
 			char x = cast(char)a[i];
 			char x = cast(char)a[i];
@@ -113,13 +105,13 @@ gb_inline bool str_eq_ignore_case(String const &a, String const &b) {
 	return false;
 	return false;
 }
 }
 
 
-void string_to_lower(String *s) {
+gb_internal void string_to_lower(String *s) {
 	for (isize i = 0; i < s->len; i++) {
 	for (isize i = 0; i < s->len; i++) {
 		s->text[i] = gb_char_to_lower(s->text[i]);
 		s->text[i] = gb_char_to_lower(s->text[i]);
 	}
 	}
 }
 }
 
 
-int string_compare(String const &x, String const &y) {
+gb_internal int string_compare(String const &x, String const &y) {
 	if (x.len != y.len || x.text != y.text) {
 	if (x.len != y.len || x.text != y.text) {
 		isize n, fast, offset, curr_block;
 		isize n, fast, offset, curr_block;
 		isize *la, *lb;
 		isize *la, *lb;
@@ -157,7 +149,7 @@ int string_compare(String const &x, String const &y) {
 	return 0;
 	return 0;
 }
 }
 
 
-isize string_index_byte(String const &s, u8 x) {
+gb_internal isize string_index_byte(String const &s, u8 x) {
 	for (isize i = 0; i < s.len; i++) {
 	for (isize i = 0; i < s.len; i++) {
 		if (s.text[i] == x) {
 		if (s.text[i] == x) {
 			return i;
 			return i;
@@ -166,37 +158,31 @@ isize string_index_byte(String const &s, u8 x) {
 	return -1;
 	return -1;
 }
 }
 
 
-GB_COMPARE_PROC(string_cmp_proc) {
-	String x = *(String *)a;
-	String y = *(String *)b;
-	return string_compare(x, y);
-}
-
-gb_inline bool str_eq(String const &a, String const &b) {
+gb_internal gb_inline bool str_eq(String const &a, String const &b) {
 	if (a.len != b.len) return false;
 	if (a.len != b.len) return false;
 	return memcmp(a.text, b.text, a.len) == 0;
 	return memcmp(a.text, b.text, a.len) == 0;
 }
 }
-gb_inline bool str_ne(String const &a, String const &b) { return !str_eq(a, b);                }
-gb_inline bool str_lt(String const &a, String const &b) { return string_compare(a, b) < 0;     }
-gb_inline bool str_gt(String const &a, String const &b) { return string_compare(a, b) > 0;     }
-gb_inline bool str_le(String const &a, String const &b) { return string_compare(a, b) <= 0;    }
-gb_inline bool str_ge(String const &a, String const &b) { return string_compare(a, b) >= 0;    }
-
-gb_inline bool operator == (String const &a, String const &b) { return str_eq(a, b); }
-gb_inline bool operator != (String const &a, String const &b) { return str_ne(a, b); }
-gb_inline bool operator <  (String const &a, String const &b) { return str_lt(a, b); }
-gb_inline bool operator >  (String const &a, String const &b) { return str_gt(a, b); }
-gb_inline bool operator <= (String const &a, String const &b) { return str_le(a, b); }
-gb_inline bool operator >= (String const &a, String const &b) { return str_ge(a, b); }
-
-template <isize N> bool operator == (String const &a, char const (&b)[N]) { return str_eq(a, make_string(cast(u8 *)b, N-1)); }
-template <isize N> bool operator != (String const &a, char const (&b)[N]) { return str_ne(a, make_string(cast(u8 *)b, N-1)); }
-template <isize N> bool operator <  (String const &a, char const (&b)[N]) { return str_lt(a, make_string(cast(u8 *)b, N-1)); }
-template <isize N> bool operator >  (String const &a, char const (&b)[N]) { return str_gt(a, make_string(cast(u8 *)b, N-1)); }
-template <isize N> bool operator <= (String const &a, char const (&b)[N]) { return str_le(a, make_string(cast(u8 *)b, N-1)); }
-template <isize N> bool operator >= (String const &a, char const (&b)[N]) { return str_ge(a, make_string(cast(u8 *)b, N-1)); }
-
-gb_inline bool string_starts_with(String const &s, String const &prefix) {
+gb_internal gb_inline bool str_ne(String const &a, String const &b) { return !str_eq(a, b);                }
+gb_internal gb_inline bool str_lt(String const &a, String const &b) { return string_compare(a, b) < 0;     }
+gb_internal gb_inline bool str_gt(String const &a, String const &b) { return string_compare(a, b) > 0;     }
+gb_internal gb_inline bool str_le(String const &a, String const &b) { return string_compare(a, b) <= 0;    }
+gb_internal gb_inline bool str_ge(String const &a, String const &b) { return string_compare(a, b) >= 0;    }
+
+gb_internal gb_inline bool operator == (String const &a, String const &b) { return str_eq(a, b); }
+gb_internal gb_inline bool operator != (String const &a, String const &b) { return str_ne(a, b); }
+gb_internal gb_inline bool operator <  (String const &a, String const &b) { return str_lt(a, b); }
+gb_internal gb_inline bool operator >  (String const &a, String const &b) { return str_gt(a, b); }
+gb_internal gb_inline bool operator <= (String const &a, String const &b) { return str_le(a, b); }
+gb_internal gb_inline bool operator >= (String const &a, String const &b) { return str_ge(a, b); }
+
+template <isize N> gb_internal bool operator == (String const &a, char const (&b)[N]) { return str_eq(a, make_string(cast(u8 *)b, N-1)); }
+template <isize N> gb_internal bool operator != (String const &a, char const (&b)[N]) { return str_ne(a, make_string(cast(u8 *)b, N-1)); }
+template <isize N> gb_internal bool operator <  (String const &a, char const (&b)[N]) { return str_lt(a, make_string(cast(u8 *)b, N-1)); }
+template <isize N> gb_internal bool operator >  (String const &a, char const (&b)[N]) { return str_gt(a, make_string(cast(u8 *)b, N-1)); }
+template <isize N> gb_internal bool operator <= (String const &a, char const (&b)[N]) { return str_le(a, make_string(cast(u8 *)b, N-1)); }
+template <isize N> gb_internal bool operator >= (String const &a, char const (&b)[N]) { return str_ge(a, make_string(cast(u8 *)b, N-1)); }
+
+gb_internal gb_inline bool string_starts_with(String const &s, String const &prefix) {
 	if (prefix.len > s.len) {
 	if (prefix.len > s.len) {
 		return false;
 		return false;
 	}
 	}
@@ -204,7 +190,7 @@ gb_inline bool string_starts_with(String const &s, String const &prefix) {
 	return substring(s, 0, prefix.len) == prefix;
 	return substring(s, 0, prefix.len) == prefix;
 }
 }
 
 
-gb_inline bool string_ends_with(String const &s, String const &suffix) {
+gb_internal gb_inline bool string_ends_with(String const &s, String const &suffix) {
 	if (suffix.len > s.len) {
 	if (suffix.len > s.len) {
 		return false;
 		return false;
 	}
 	}
@@ -212,7 +198,7 @@ gb_inline bool string_ends_with(String const &s, String const &suffix) {
 	return substring(s, s.len-suffix.len, s.len) == suffix;
 	return substring(s, s.len-suffix.len, s.len) == suffix;
 }
 }
 
 
-gb_inline bool string_starts_with(String const &s, u8 prefix) {
+gb_internal gb_inline bool string_starts_with(String const &s, u8 prefix) {
 	if (1 > s.len) {
 	if (1 > s.len) {
 		return false;
 		return false;
 	}
 	}
@@ -221,7 +207,7 @@ gb_inline bool string_starts_with(String const &s, u8 prefix) {
 }
 }
 
 
 
 
-gb_inline bool string_ends_with(String const &s, u8 suffix) {
+gb_internal gb_inline bool string_ends_with(String const &s, u8 suffix) {
 	if (1 > s.len) {
 	if (1 > s.len) {
 		return false;
 		return false;
 	}
 	}
@@ -231,7 +217,7 @@ gb_inline bool string_ends_with(String const &s, u8 suffix) {
 
 
 
 
 
 
-gb_inline String string_trim_starts_with(String const &s, String const &prefix) {
+gb_internal gb_inline String string_trim_starts_with(String const &s, String const &prefix) {
 	if (string_starts_with(s, prefix)) {
 	if (string_starts_with(s, prefix)) {
 		return substring(s, prefix.len, s.len);
 		return substring(s, prefix.len, s.len);
 	}
 	}
@@ -239,7 +225,7 @@ gb_inline String string_trim_starts_with(String const &s, String const &prefix)
 }
 }
 
 
 
 
-gb_inline isize string_extension_position(String const &str) {
+gb_internal gb_inline isize string_extension_position(String const &str) {
 	isize dot_pos = -1;
 	isize dot_pos = -1;
 	isize i = str.len;
 	isize i = str.len;
 	while (i --> 0) {
 	while (i --> 0) {
@@ -254,7 +240,7 @@ gb_inline isize string_extension_position(String const &str) {
 	return dot_pos;
 	return dot_pos;
 }
 }
 
 
-String path_extension(String const &str, bool include_dot = true) {
+gb_internal String path_extension(String const &str, bool include_dot = true) {
 	isize pos = string_extension_position(str);
 	isize pos = string_extension_position(str);
 	if (pos < 0) {
 	if (pos < 0) {
 		return make_string(nullptr, 0);
 		return make_string(nullptr, 0);
@@ -262,7 +248,7 @@ String path_extension(String const &str, bool include_dot = true) {
 	return substring(str, include_dot ? pos : pos + 1, str.len);
 	return substring(str, include_dot ? pos : pos + 1, str.len);
 }
 }
 
 
-String string_trim_whitespace(String str) {
+gb_internal String string_trim_whitespace(String str) {
 	while (str.len > 0 && rune_is_whitespace(str[str.len-1])) {
 	while (str.len > 0 && rune_is_whitespace(str[str.len-1])) {
 		str.len--;
 		str.len--;
 	}
 	}
@@ -279,7 +265,7 @@ String string_trim_whitespace(String str) {
 	return str;
 	return str;
 }
 }
 
 
-bool string_contains_char(String const &s, u8 c) {
+gb_internal bool string_contains_char(String const &s, u8 c) {
 	isize i;
 	isize i;
 	for (i = 0; i < s.len; i++) {
 	for (i = 0; i < s.len; i++) {
 		if (s[i] == c)
 		if (s[i] == c)
@@ -288,7 +274,7 @@ bool string_contains_char(String const &s, u8 c) {
 	return false;
 	return false;
 }
 }
 
 
-String filename_from_path(String s) {
+gb_internal String filename_from_path(String s) {
 	isize i = string_extension_position(s);
 	isize i = string_extension_position(s);
 	if (i >= 0) {
 	if (i >= 0) {
 		s = substring(s, 0, i);
 		s = substring(s, 0, i);
@@ -307,7 +293,7 @@ String filename_from_path(String s) {
 	return make_string(nullptr, 0);
 	return make_string(nullptr, 0);
 }
 }
 
 
-String concatenate_strings(gbAllocator a, String const &x, String const &y) {
+gb_internal String concatenate_strings(gbAllocator a, String const &x, String const &y) {
 	isize len = x.len+y.len;
 	isize len = x.len+y.len;
 	u8 *data = gb_alloc_array(a, u8, len+1);
 	u8 *data = gb_alloc_array(a, u8, len+1);
 	gb_memmove(data,       x.text, x.len);
 	gb_memmove(data,       x.text, x.len);
@@ -315,7 +301,7 @@ String concatenate_strings(gbAllocator a, String const &x, String const &y) {
 	data[len] = 0;
 	data[len] = 0;
 	return make_string(data, len);
 	return make_string(data, len);
 }
 }
-String concatenate3_strings(gbAllocator a, String const &x, String const &y, String const &z) {
+gb_internal String concatenate3_strings(gbAllocator a, String const &x, String const &y, String const &z) {
 	isize len = x.len+y.len+z.len;
 	isize len = x.len+y.len+z.len;
 	u8 *data = gb_alloc_array(a, u8, len+1);
 	u8 *data = gb_alloc_array(a, u8, len+1);
 	gb_memmove(data,             x.text, x.len);
 	gb_memmove(data,             x.text, x.len);
@@ -324,7 +310,7 @@ String concatenate3_strings(gbAllocator a, String const &x, String const &y, Str
 	data[len] = 0;
 	data[len] = 0;
 	return make_string(data, len);
 	return make_string(data, len);
 }
 }
-String concatenate4_strings(gbAllocator a, String const &x, String const &y, String const &z, String const &w) {
+gb_internal String concatenate4_strings(gbAllocator a, String const &x, String const &y, String const &z, String const &w) {
 	isize len = x.len+y.len+z.len+w.len;
 	isize len = x.len+y.len+z.len+w.len;
 	u8 *data = gb_alloc_array(a, u8, len+1);
 	u8 *data = gb_alloc_array(a, u8, len+1);
 	gb_memmove(data,                   x.text, x.len);
 	gb_memmove(data,                   x.text, x.len);
@@ -335,7 +321,7 @@ String concatenate4_strings(gbAllocator a, String const &x, String const &y, Str
 	return make_string(data, len);
 	return make_string(data, len);
 }
 }
 
 
-String string_join_and_quote(gbAllocator a, Array<String> strings) {
+gb_internal String string_join_and_quote(gbAllocator a, Array<String> strings) {
 	if (!strings.count) {
 	if (!strings.count) {
 		return make_string(nullptr, 0);
 		return make_string(nullptr, 0);
 	}
 	}
@@ -356,7 +342,7 @@ String string_join_and_quote(gbAllocator a, Array<String> strings) {
 	return make_string(cast(u8 *) s, gb_string_length(s));
 	return make_string(cast(u8 *) s, gb_string_length(s));
 }
 }
 
 
-String copy_string(gbAllocator a, String const &s) {
+gb_internal String copy_string(gbAllocator a, String const &s) {
 	u8 *data = gb_alloc_array(a, u8, s.len+1);
 	u8 *data = gb_alloc_array(a, u8, s.len+1);
 	gb_memmove(data, s.text, s.len);
 	gb_memmove(data, s.text, s.len);
 	data[s.len] = 0;
 	data[s.len] = 0;
@@ -367,17 +353,17 @@ String copy_string(gbAllocator a, String const &s) {
 
 
 
 
 #if defined(GB_SYSTEM_WINDOWS)
 #if defined(GB_SYSTEM_WINDOWS)
-	int convert_multibyte_to_widechar(char const *multibyte_input, int input_length, wchar_t *output, int output_size) {
+	gb_internal int convert_multibyte_to_widechar(char const *multibyte_input, int input_length, wchar_t *output, int output_size) {
 		return MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, multibyte_input, input_length, output, output_size);
 		return MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, multibyte_input, input_length, output, output_size);
 	}
 	}
-	int convert_widechar_to_multibyte(wchar_t const *widechar_input, int input_length, char *output, int output_size) {
+	gb_internal int convert_widechar_to_multibyte(wchar_t const *widechar_input, int input_length, char *output, int output_size) {
 		return WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, widechar_input, input_length, output, output_size, nullptr, nullptr);
 		return WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, widechar_input, input_length, output, output_size, nullptr, nullptr);
 	}
 	}
 #elif defined(GB_SYSTEM_UNIX) || defined(GB_SYSTEM_OSX)
 #elif defined(GB_SYSTEM_UNIX) || defined(GB_SYSTEM_OSX)
 
 
 	#include <iconv.h>
 	#include <iconv.h>
 
 
-	int convert_multibyte_to_widechar(char const *multibyte_input, usize input_length, wchar_t *output, usize output_size) {
+	gb_internal int convert_multibyte_to_widechar(char const *multibyte_input, usize input_length, wchar_t *output, usize output_size) {
 		iconv_t conv = iconv_open("WCHAR_T", "UTF-8");
 		iconv_t conv = iconv_open("WCHAR_T", "UTF-8");
 		size_t result = iconv(conv, cast(char **)&multibyte_input, &input_length, cast(char **)&output, &output_size);
 		size_t result = iconv(conv, cast(char **)&multibyte_input, &input_length, cast(char **)&output, &output_size);
 		iconv_close(conv);
 		iconv_close(conv);
@@ -385,7 +371,7 @@ String copy_string(gbAllocator a, String const &s) {
 		return cast(int)result;
 		return cast(int)result;
 	}
 	}
 
 
-	int convert_widechar_to_multibyte(wchar_t const *widechar_input, usize input_length, char* output, usize output_size) {
+	gb_internal int convert_widechar_to_multibyte(wchar_t const *widechar_input, usize input_length, char* output, usize output_size) {
 		iconv_t conv = iconv_open("UTF-8", "WCHAR_T");
 		iconv_t conv = iconv_open("UTF-8", "WCHAR_T");
 		size_t result = iconv(conv, cast(char**) &widechar_input, &input_length, cast(char **)&output, &output_size);
 		size_t result = iconv(conv, cast(char**) &widechar_input, &input_length, cast(char **)&output, &output_size);
 		iconv_close(conv);
 		iconv_close(conv);
@@ -400,7 +386,7 @@ String copy_string(gbAllocator a, String const &s) {
 
 
 
 
 // TODO(bill): Make this non-windows specific
 // TODO(bill): Make this non-windows specific
-String16 string_to_string16(gbAllocator a, String s) {
+gb_internal String16 string_to_string16(gbAllocator a, String s) {
 	int len, len1;
 	int len, len1;
 	wchar_t *text;
 	wchar_t *text;
 
 
@@ -426,7 +412,7 @@ String16 string_to_string16(gbAllocator a, String s) {
 }
 }
 
 
 
 
-String string16_to_string(gbAllocator a, String16 s) {
+gb_internal String string16_to_string(gbAllocator a, String16 s) {
 	int len, len1;
 	int len, len1;
 	u8 *text;
 	u8 *text;
 
 
@@ -458,7 +444,7 @@ String string16_to_string(gbAllocator a, String16 s) {
 
 
 
 
 
 
-bool is_printable(Rune r) {
+gb_internal bool is_printable(Rune r) {
 	if (r <= 0xff) {
 	if (r <= 0xff) {
 		if (0x20 <= r && r <= 0x7e) {
 		if (0x20 <= r && r <= 0x7e) {
 			return true;
 			return true;
@@ -473,7 +459,7 @@ bool is_printable(Rune r) {
 
 
 gb_global char const lower_hex[] = "0123456789abcdef";
 gb_global char const lower_hex[] = "0123456789abcdef";
 
 
-String quote_to_ascii(gbAllocator a, String str, u8 quote='"') {
+gb_internal String quote_to_ascii(gbAllocator a, String str, u8 quote='"') {
 	u8 *s = str.text;
 	u8 *s = str.text;
 	isize n = str.len;
 	isize n = str.len;
 	auto buf = array_make<u8>(a, 0, n);
 	auto buf = array_make<u8>(a, 0, n);
@@ -548,7 +534,7 @@ String quote_to_ascii(gbAllocator a, String str, u8 quote='"') {
 
 
 
 
 
 
-bool unquote_char(String s, u8 quote, Rune *rune, bool *multiple_bytes, String *tail_string) {
+gb_internal bool unquote_char(String s, u8 quote, Rune *rune, bool *multiple_bytes, String *tail_string) {
 	u8 c;
 	u8 c;
 
 
 	if (s[0] == quote &&
 	if (s[0] == quote &&
@@ -657,7 +643,7 @@ bool unquote_char(String s, u8 quote, Rune *rune, bool *multiple_bytes, String *
 }
 }
 
 
 
 
-String strip_carriage_return(gbAllocator a, String s) {
+gb_internal String strip_carriage_return(gbAllocator a, String s) {
 	isize buf_len = s.len;
 	isize buf_len = s.len;
 	u8 *buf = gb_alloc_array(a, u8, buf_len);
 	u8 *buf = gb_alloc_array(a, u8, buf_len);
 	isize i = 0;
 	isize i = 0;
@@ -675,7 +661,7 @@ String strip_carriage_return(gbAllocator a, String s) {
 // 0 == failure
 // 0 == failure
 // 1 == original memory
 // 1 == original memory
 // 2 == new allocation
 // 2 == new allocation
-i32 unquote_string(gbAllocator a, String *s_, u8 quote=0, bool has_carriage_return=false) {
+gb_internal i32 unquote_string(gbAllocator a, String *s_, u8 quote=0, bool has_carriage_return=false) {
 	String s = *s_;
 	String s = *s_;
 	isize n = s.len;
 	isize n = s.len;
 	if (quote == 0) {
 	if (quote == 0) {
@@ -761,7 +747,7 @@ i32 unquote_string(gbAllocator a, String *s_, u8 quote=0, bool has_carriage_retu
 
 
 
 
 
 
-bool string_is_valid_identifier(String str) {
+gb_internal bool string_is_valid_identifier(String str) {
 	if (str.len <= 0) return false;
 	if (str.len <= 0) return false;
 
 
 	isize rune_count = 0;
 	isize rune_count = 0;

+ 58 - 37
src/string_map.cpp

@@ -3,7 +3,7 @@ struct StringHashKey {
 	String string;
 	String string;
 };
 };
 
 
-gb_inline StringHashKey string_hash_string(String const &s) {
+gb_internal gb_inline StringHashKey string_hash_string(String const &s) {
 	StringHashKey hash_key = {};
 	StringHashKey hash_key = {};
 	hash_key.hash = fnv32a(s.text, s.len);
 	hash_key.hash = fnv32a(s.text, s.len);
 	hash_key.string = s;
 	hash_key.string = s;
@@ -11,15 +11,13 @@ gb_inline StringHashKey string_hash_string(String const &s) {
 }
 }
 
 
 
 
-bool string_hash_key_equal(StringHashKey const &a, StringHashKey const &b) {
+gb_internal gb_inline bool string_hash_key_equal(StringHashKey const &a, StringHashKey const &b) {
 	if (a.hash == b.hash) {
 	if (a.hash == b.hash) {
 		// NOTE(bill): If two string's hashes collide, compare the strings themselves
 		// NOTE(bill): If two string's hashes collide, compare the strings themselves
 		return a.string == b.string;
 		return a.string == b.string;
 	}
 	}
 	return false;
 	return false;
 }
 }
-bool operator==(StringHashKey const &a, StringHashKey const &b) { return string_hash_key_equal(a, b); }
-bool operator!=(StringHashKey const &a, StringHashKey const &b) { return !string_hash_key_equal(a, b); }
 
 
 template <typename T>
 template <typename T>
 struct StringMapEntry {
 struct StringMapEntry {
@@ -30,34 +28,36 @@ 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;
 };
 };
 
 
 
 
-template <typename T> void string_map_init             (StringMap<T> *h, gbAllocator a, isize capacity = 16);
-template <typename T> void string_map_destroy          (StringMap<T> *h);
+template <typename T> gb_internal void string_map_init             (StringMap<T> *h, gbAllocator a, isize capacity = 16);
+template <typename T> gb_internal void string_map_destroy          (StringMap<T> *h);
 
 
-template <typename T> T *  string_map_get              (StringMap<T> *h, char const *key);
-template <typename T> T *  string_map_get              (StringMap<T> *h, String const &key);
-template <typename T> T *  string_map_get              (StringMap<T> *h, StringHashKey const &key);
+template <typename T> gb_internal T *  string_map_get              (StringMap<T> *h, char const *key);
+template <typename T> gb_internal T *  string_map_get              (StringMap<T> *h, String const &key);
+template <typename T> gb_internal T *  string_map_get              (StringMap<T> *h, StringHashKey const &key);
 
 
-template <typename T> T &  string_map_must_get         (StringMap<T> *h, char const *key);
-template <typename T> T &  string_map_must_get         (StringMap<T> *h, String const &key);
-template <typename T> T &  string_map_must_get         (StringMap<T> *h, StringHashKey const &key);
+template <typename T> gb_internal T &  string_map_must_get         (StringMap<T> *h, char const *key);
+template <typename T> gb_internal T &  string_map_must_get         (StringMap<T> *h, String const &key);
+template <typename T> gb_internal T &  string_map_must_get         (StringMap<T> *h, StringHashKey const &key);
 
 
-template <typename T> void string_map_set              (StringMap<T> *h, StringHashKey const &key, T const &value);
-template <typename T> void string_map_set              (StringMap<T> *h, String const &key, T const &value);
-template <typename T> void string_map_set              (StringMap<T> *h, char const *key,   T const &value);
+template <typename T> gb_internal void string_map_set              (StringMap<T> *h, StringHashKey const &key, T const &value);
+template <typename T> gb_internal void string_map_set              (StringMap<T> *h, String const &key, T const &value);
+template <typename T> gb_internal void string_map_set              (StringMap<T> *h, char const *key,   T const &value);
 
 
-template <typename T> void string_map_remove           (StringMap<T> *h, StringHashKey const &key);
-template <typename T> void string_map_clear            (StringMap<T> *h);
-template <typename T> void string_map_grow             (StringMap<T> *h);
-template <typename T> void string_map_rehash           (StringMap<T> *h, isize new_count);
-template <typename T> void string_map_reserve          (StringMap<T> *h, isize cap);
+template <typename T> gb_internal void string_map_remove           (StringMap<T> *h, StringHashKey const &key);
+template <typename T> gb_internal void string_map_clear            (StringMap<T> *h);
+template <typename T> gb_internal void string_map_grow             (StringMap<T> *h);
+template <typename T> gb_internal void string_map_rehash           (StringMap<T> *h, isize new_count);
+template <typename T> gb_internal void string_map_reserve          (StringMap<T> *h, isize cap);
 
 
 template <typename T>
 template <typename T>
-gb_inline void string_map_init(StringMap<T> *h, gbAllocator a, isize capacity) {
+gb_internal gb_inline void string_map_init(StringMap<T> *h, gbAllocator a, isize capacity) {
 	capacity = next_pow2_isize(capacity);
 	capacity = next_pow2_isize(capacity);
 	slice_init(&h->hashes,  a, capacity);
 	slice_init(&h->hashes,  a, capacity);
 	array_init(&h->entries, a, 0, capacity);
 	array_init(&h->entries, a, 0, capacity);
@@ -67,7 +67,7 @@ gb_inline void string_map_init(StringMap<T> *h, gbAllocator a, isize capacity) {
 }
 }
 
 
 template <typename T>
 template <typename T>
-gb_inline void string_map_destroy(StringMap<T> *h) {
+gb_internal gb_inline void string_map_destroy(StringMap<T> *h) {
 	slice_free(&h->hashes, h->entries.allocator);
 	slice_free(&h->hashes, h->entries.allocator);
 	array_free(&h->entries);
 	array_free(&h->entries);
 }
 }
@@ -128,7 +128,7 @@ gb_inline void string_map_grow(StringMap<T> *h) {
 
 
 
 
 template <typename T>
 template <typename T>
-void string_map_reset_entries(StringMap<T> *h) {
+gb_internal void string_map_reset_entries(StringMap<T> *h) {
 	for (isize i = 0; i < h->hashes.count; i++) {
 	for (isize i = 0; i < h->hashes.count; i++) {
 		h->hashes.data[i] = MAP_SENTINEL;
 		h->hashes.data[i] = MAP_SENTINEL;
 	}
 	}
@@ -146,7 +146,7 @@ void string_map_reset_entries(StringMap<T> *h) {
 }
 }
 
 
 template <typename T>
 template <typename T>
-void string_map_reserve(StringMap<T> *h, isize cap) {
+gb_internal void string_map_reserve(StringMap<T> *h, isize cap) {
 	array_reserve(&h->entries, cap);
 	array_reserve(&h->entries, cap);
 	if (h->entries.count*2 < h->hashes.count) {
 	if (h->entries.count*2 < h->hashes.count) {
 		return;
 		return;
@@ -157,12 +157,12 @@ void string_map_reserve(StringMap<T> *h, isize cap) {
 
 
 
 
 template <typename T>
 template <typename T>
-void string_map_rehash(StringMap<T> *h, isize new_count) {
+gb_internal void string_map_rehash(StringMap<T> *h, isize new_count) {
 	string_map_reserve(h, new_count);
 	string_map_reserve(h, new_count);
 }
 }
 
 
 template <typename T>
 template <typename T>
-T *string_map_get(StringMap<T> *h, StringHashKey const &key) {
+gb_internal T *string_map_get(StringMap<T> *h, StringHashKey const &key) {
 	isize index = string_map__find(h, key).entry_index;
 	isize index = string_map__find(h, key).entry_index;
 	if (index != MAP_SENTINEL) {
 	if (index != MAP_SENTINEL) {
 		return &h->entries.data[index].value;
 		return &h->entries.data[index].value;
@@ -171,34 +171,34 @@ T *string_map_get(StringMap<T> *h, StringHashKey const &key) {
 }
 }
 
 
 template <typename T>
 template <typename T>
-gb_inline T *string_map_get(StringMap<T> *h, String const &key) {
+gb_internal gb_inline T *string_map_get(StringMap<T> *h, String const &key) {
 	return string_map_get(h, string_hash_string(key));
 	return string_map_get(h, string_hash_string(key));
 }
 }
 
 
 template <typename T>
 template <typename T>
-gb_inline T *string_map_get(StringMap<T> *h, char const *key) {
+gb_internal gb_inline T *string_map_get(StringMap<T> *h, char const *key) {
 	return string_map_get(h, string_hash_string(make_string_c(key)));
 	return string_map_get(h, string_hash_string(make_string_c(key)));
 }
 }
 
 
 template <typename T>
 template <typename T>
-T &string_map_must_get(StringMap<T> *h, StringHashKey const &key) {
+gb_internal T &string_map_must_get(StringMap<T> *h, StringHashKey const &key) {
 	isize index = string_map__find(h, key).entry_index;
 	isize index = string_map__find(h, key).entry_index;
 	GB_ASSERT(index != MAP_SENTINEL);
 	GB_ASSERT(index != MAP_SENTINEL);
 	return h->entries.data[index].value;
 	return h->entries.data[index].value;
 }
 }
 
 
 template <typename T>
 template <typename T>
-gb_inline T &string_map_must_get(StringMap<T> *h, String const &key) {
+gb_internal gb_inline T &string_map_must_get(StringMap<T> *h, String const &key) {
 	return string_map_must_get(h, string_hash_string(key));
 	return string_map_must_get(h, string_hash_string(key));
 }
 }
 
 
 template <typename T>
 template <typename T>
-gb_inline T &string_map_must_get(StringMap<T> *h, char const *key) {
+gb_internal gb_inline T &string_map_must_get(StringMap<T> *h, char const *key) {
 	return string_map_must_get(h, string_hash_string(make_string_c(key)));
 	return string_map_must_get(h, string_hash_string(make_string_c(key)));
 }
 }
 
 
 template <typename T>
 template <typename T>
-void string_map_set(StringMap<T> *h, StringHashKey const &key, T const &value) {
+gb_internal void string_map_set(StringMap<T> *h, StringHashKey const &key, T const &value) {
 	MapIndex index;
 	MapIndex index;
 	MapFindResult fr;
 	MapFindResult fr;
 	if (h->hashes.count == 0) {
 	if (h->hashes.count == 0) {
@@ -223,18 +223,18 @@ void string_map_set(StringMap<T> *h, StringHashKey const &key, T const &value) {
 }
 }
 
 
 template <typename T>
 template <typename T>
-gb_inline void string_map_set(StringMap<T> *h, String const &key, T const &value) {
+gb_internal gb_inline void string_map_set(StringMap<T> *h, String const &key, T const &value) {
 	string_map_set(h, string_hash_string(key), value);
 	string_map_set(h, string_hash_string(key), value);
 }
 }
 
 
 template <typename T>
 template <typename T>
-gb_inline void string_map_set(StringMap<T> *h, char const *key, T const &value) {
+gb_internal gb_inline void string_map_set(StringMap<T> *h, char const *key, T const &value) {
 	string_map_set(h, string_hash_string(make_string_c(key)), value);
 	string_map_set(h, string_hash_string(make_string_c(key)), value);
 }
 }
 
 
 
 
 template <typename T>
 template <typename T>
-void string_map__erase(StringMap<T> *h, MapFindResult const &fr) {
+gb_internal void string_map__erase(StringMap<T> *h, MapFindResult const &fr) {
 	MapFindResult last;
 	MapFindResult last;
 	if (fr.entry_prev == MAP_SENTINEL) {
 	if (fr.entry_prev == MAP_SENTINEL) {
 		h->hashes.data[fr.hash_index] = h->entries.data[fr.entry_index].next;
 		h->hashes.data[fr.hash_index] = h->entries.data[fr.entry_index].next;
@@ -255,7 +255,7 @@ void string_map__erase(StringMap<T> *h, MapFindResult const &fr) {
 }
 }
 
 
 template <typename T>
 template <typename T>
-void string_map_remove(StringMap<T> *h, StringHashKey const &key) {
+gb_internal void string_map_remove(StringMap<T> *h, StringHashKey const &key) {
 	MapFindResult fr = string_map__find(h, key);
 	MapFindResult fr = string_map__find(h, key);
 	if (fr.entry_index != MAP_SENTINEL) {
 	if (fr.entry_index != MAP_SENTINEL) {
 		string_map__erase(h, fr);
 		string_map__erase(h, fr);
@@ -263,10 +263,31 @@ void string_map_remove(StringMap<T> *h, StringHashKey const &key) {
 }
 }
 
 
 template <typename T>
 template <typename T>
-gb_inline void string_map_clear(StringMap<T> *h) {
+gb_internal gb_inline void string_map_clear(StringMap<T> *h) {
 	array_clear(&h->entries);
 	array_clear(&h->entries);
 	for (isize i = 0; i < h->hashes.count; i++) {
 	for (isize i = 0; i < h->hashes.count; i++) {
 		h->hashes.data[i] = MAP_SENTINEL;
 		h->hashes.data[i] = MAP_SENTINEL;
 	}
 	}
 }
 }
 
 
+
+
+template <typename T>
+gb_internal StringMapEntry<T> *begin(StringMap<T> &m) {
+	return m.entries.data;
+}
+template <typename T>
+gb_internal StringMapEntry<T> const *begin(StringMap<T> const &m) {
+	return m.entries.data;
+}
+
+
+template <typename T>
+gb_internal StringMapEntry<T> *end(StringMap<T> &m) {
+	return m.entries.data + m.entries.count;
+}
+
+template <typename T>
+gb_internal StringMapEntry<T> const *end(StringMap<T> const &m) {
+	return m.entries.data + m.entries.count;
+}

+ 40 - 22
src/string_set.cpp

@@ -10,18 +10,18 @@ struct StringSet {
 };
 };
 
 
 
 
-void string_set_init   (StringSet *s, gbAllocator a, isize capacity = 16);
-void string_set_destroy(StringSet *s);
-void string_set_add    (StringSet *s, String const &str);
-bool string_set_update (StringSet *s, String const &str); // returns true if it previously existed
-bool string_set_exists (StringSet *s, String const &str);
-void string_set_remove (StringSet *s, String const &str);
-void string_set_clear  (StringSet *s);
-void string_set_grow   (StringSet *s);
-void string_set_rehash (StringSet *s, isize new_count);
-
-
-gb_inline void string_set_init(StringSet *s, gbAllocator a, isize capacity) {
+gb_internal void string_set_init   (StringSet *s, gbAllocator a, isize capacity = 16);
+gb_internal void string_set_destroy(StringSet *s);
+gb_internal void string_set_add    (StringSet *s, String const &str);
+gb_internal bool string_set_update (StringSet *s, String const &str); // returns true if it previously existed
+gb_internal bool string_set_exists (StringSet *s, String const &str);
+gb_internal void string_set_remove (StringSet *s, String const &str);
+gb_internal void string_set_clear  (StringSet *s);
+gb_internal void string_set_grow   (StringSet *s);
+gb_internal void string_set_rehash (StringSet *s, isize new_count);
+
+
+gb_internal gb_inline void string_set_init(StringSet *s, gbAllocator a, isize capacity) {
 	capacity = next_pow2_isize(gb_max(16, capacity));
 	capacity = next_pow2_isize(gb_max(16, capacity));
 	
 	
 	slice_init(&s->hashes,  a, capacity);
 	slice_init(&s->hashes,  a, capacity);
@@ -31,7 +31,7 @@ gb_inline void string_set_init(StringSet *s, gbAllocator a, isize capacity) {
 	}
 	}
 }
 }
 
 
-gb_inline void string_set_destroy(StringSet *s) {
+gb_internal gb_inline void string_set_destroy(StringSet *s) {
 	slice_free(&s->hashes, s->entries.allocator);
 	slice_free(&s->hashes, s->entries.allocator);
 	array_free(&s->entries);
 	array_free(&s->entries);
 }
 }
@@ -82,13 +82,13 @@ gb_internal b32 string_set__full(StringSet *s) {
 	return 0.75f * s->hashes.count <= s->entries.count;
 	return 0.75f * s->hashes.count <= s->entries.count;
 }
 }
 
 
-gb_inline void string_set_grow(StringSet *s) {
+gb_internal gb_inline void string_set_grow(StringSet *s) {
 	isize new_count = gb_max(s->hashes.count<<1, 16);
 	isize new_count = gb_max(s->hashes.count<<1, 16);
 	string_set_rehash(s, new_count);
 	string_set_rehash(s, new_count);
 }
 }
 
 
 
 
-void string_set_reset_entries(StringSet *s) {
+gb_internal void string_set_reset_entries(StringSet *s) {
 	for (isize i = 0; i < s->hashes.count; i++) {
 	for (isize i = 0; i < s->hashes.count; i++) {
 		s->hashes.data[i] = MAP_SENTINEL;
 		s->hashes.data[i] = MAP_SENTINEL;
 	}
 	}
@@ -105,7 +105,7 @@ void string_set_reset_entries(StringSet *s) {
 	}
 	}
 }
 }
 
 
-void string_set_reserve(StringSet *s, isize cap) {
+gb_internal void string_set_reserve(StringSet *s, isize cap) {
 	array_reserve(&s->entries, cap);
 	array_reserve(&s->entries, cap);
 	if (s->entries.count*2 < s->hashes.count) {
 	if (s->entries.count*2 < s->hashes.count) {
 		return;
 		return;
@@ -115,7 +115,7 @@ void string_set_reserve(StringSet *s, isize cap) {
 }
 }
 
 
 
 
-void string_set_rehash(StringSet *s, isize new_count) {
+gb_internal void string_set_rehash(StringSet *s, isize new_count) {
 	string_set_reserve(s, new_count);
 	string_set_reserve(s, new_count);
 }
 }
 
 
@@ -125,7 +125,7 @@ gb_inline bool string_set_exists(StringSet *s, String const &str) {
 	return index != MAP_SENTINEL;
 	return index != MAP_SENTINEL;
 }
 }
 
 
-void string_set_add(StringSet *s, String const &str) {
+gb_internal void string_set_add(StringSet *s, String const &str) {
 	MapIndex index;
 	MapIndex index;
 	MapFindResult fr;
 	MapFindResult fr;
 	StringHashKey key = string_hash_string(str);
 	StringHashKey key = string_hash_string(str);
@@ -150,7 +150,7 @@ void string_set_add(StringSet *s, String const &str) {
 	}
 	}
 }
 }
 
 
-bool string_set_update(StringSet *s, String const &str) {
+gb_internal bool string_set_update(StringSet *s, String const &str) {
 	bool exists = false;
 	bool exists = false;
 	MapIndex index;
 	MapIndex index;
 	MapFindResult fr;
 	MapFindResult fr;
@@ -179,7 +179,7 @@ bool string_set_update(StringSet *s, String const &str) {
 }
 }
 
 
 
 
-void string_set__erase(StringSet *s, MapFindResult fr) {
+gb_internal void string_set__erase(StringSet *s, MapFindResult fr) {
 	MapFindResult last;
 	MapFindResult last;
 	if (fr.entry_prev == MAP_SENTINEL) {
 	if (fr.entry_prev == MAP_SENTINEL) {
 		s->hashes[fr.hash_index] = s->entries[fr.entry_index].next;
 		s->hashes[fr.hash_index] = s->entries[fr.entry_index].next;
@@ -201,7 +201,7 @@ void string_set__erase(StringSet *s, MapFindResult fr) {
 	}
 	}
 }
 }
 
 
-void string_set_remove(StringSet *s, String const &str) {
+gb_internal void string_set_remove(StringSet *s, String const &str) {
 	StringHashKey key = string_hash_string(str);
 	StringHashKey key = string_hash_string(str);
 	MapFindResult fr = string_set__find(s, key);
 	MapFindResult fr = string_set__find(s, key);
 	if (fr.entry_index != MAP_SENTINEL) {
 	if (fr.entry_index != MAP_SENTINEL) {
@@ -209,9 +209,27 @@ void string_set_remove(StringSet *s, String const &str) {
 	}
 	}
 }
 }
 
 
-gb_inline void string_set_clear(StringSet *s) {
+gb_internal gb_inline void string_set_clear(StringSet *s) {
 	array_clear(&s->entries);
 	array_clear(&s->entries);
 	for_array(i, s->hashes) {
 	for_array(i, s->hashes) {
 		s->hashes.data[i] = MAP_SENTINEL;
 		s->hashes.data[i] = MAP_SENTINEL;
 	}
 	}
 }
 }
+
+
+
+gb_internal StringSetEntry *begin(StringSet &m) {
+	return m.entries.data;
+}
+gb_internal StringSetEntry const *begin(StringSet const &m) {
+	return m.entries.data;
+}
+
+
+gb_internal StringSetEntry *end(StringSet &m) {
+	return m.entries.data + m.entries.count;
+}
+
+gb_internal StringSetEntry const *end(StringSet const &m) {
+	return m.entries.data + m.entries.count;
+}

+ 28 - 27
src/thread_pool.cpp

@@ -1,14 +1,25 @@
 // thread_pool.cpp
 // thread_pool.cpp
 
 
+struct WorkerTask;
+struct ThreadPool;
+
 #define WORKER_TASK_PROC(name) isize name(void *data)
 #define WORKER_TASK_PROC(name) isize name(void *data)
 typedef WORKER_TASK_PROC(WorkerTaskProc);
 typedef WORKER_TASK_PROC(WorkerTaskProc);
 
 
+gb_internal void thread_pool_init(ThreadPool *pool, gbAllocator const &a, isize thread_count, char const *worker_name);
+gb_internal void thread_pool_destroy(ThreadPool *pool);
+gb_internal bool thread_pool_add_task(ThreadPool *pool, WorkerTaskProc *proc, void *data);
+gb_internal void thread_pool_wait(ThreadPool *pool);
+
+
 struct WorkerTask {
 struct WorkerTask {
 	WorkerTask *    next;
 	WorkerTask *    next;
 	WorkerTaskProc *do_work;
 	WorkerTaskProc *do_work;
 	void *          data;
 	void *          data;
+	ThreadPool *    pool;
 };
 };
 
 
+
 struct ThreadPool {
 struct ThreadPool {
 	gbAllocator   allocator;
 	gbAllocator   allocator;
 	BlockingMutex mutex;
 	BlockingMutex mutex;
@@ -23,9 +34,9 @@ struct ThreadPool {
 	
 	
 };
 };
 
 
-THREAD_PROC(thread_pool_thread_proc);
+gb_internal THREAD_PROC(thread_pool_thread_proc);
 
 
-void thread_pool_init(ThreadPool *pool, gbAllocator const &a, isize thread_count, char const *worker_name) {
+gb_internal void thread_pool_init(ThreadPool *pool, gbAllocator const &a, isize thread_count, char const *worker_name) {
 	pool->allocator = a;
 	pool->allocator = a;
 	pool->stop = false;
 	pool->stop = false;
 	mutex_init(&pool->mutex);
 	mutex_init(&pool->mutex);
@@ -34,16 +45,11 @@ void thread_pool_init(ThreadPool *pool, gbAllocator const &a, isize thread_count
 	slice_init(&pool->threads, a, thread_count);
 	slice_init(&pool->threads, a, thread_count);
 	for_array(i, pool->threads) {
 	for_array(i, pool->threads) {
 		Thread *t = &pool->threads[i];
 		Thread *t = &pool->threads[i];
-		thread_init(t);
-	}
-	
-	for_array(i, pool->threads) {
-		Thread *t = &pool->threads[i];
-		thread_start(t, thread_pool_thread_proc, pool);
+		thread_init_and_start(t, thread_pool_thread_proc, pool);
 	}
 	}
 }
 }
 
 
-void thread_pool_destroy(ThreadPool *pool) {
+gb_internal void thread_pool_destroy(ThreadPool *pool) {
 	mutex_lock(&pool->mutex);
 	mutex_lock(&pool->mutex);
 	pool->stop = true;
 	pool->stop = true;
 	condition_broadcast(&pool->task_cond);
 	condition_broadcast(&pool->task_cond);
@@ -51,65 +57,60 @@ void thread_pool_destroy(ThreadPool *pool) {
 
 
 	for_array(i, pool->threads) {
 	for_array(i, pool->threads) {
 		Thread *t = &pool->threads[i];
 		Thread *t = &pool->threads[i];
-		thread_join(t);
+		thread_join_and_destroy(t);
 	}
 	}
-	
-	for_array(i, pool->threads) {
-		Thread *t = &pool->threads[i];
-		thread_destroy(t);
-	}
-	
+
 	gb_free(pool->allocator, pool->threads.data);
 	gb_free(pool->allocator, pool->threads.data);
 	mutex_destroy(&pool->mutex);
 	mutex_destroy(&pool->mutex);
 	condition_destroy(&pool->task_cond);
 	condition_destroy(&pool->task_cond);
 }
 }
 
 
-bool thread_pool_queue_empty(ThreadPool *pool) {
+gb_internal bool thread_pool_queue_empty(ThreadPool *pool) {
 	return pool->task_queue == nullptr;
 	return pool->task_queue == nullptr;
 }
 }
 
 
-WorkerTask *thread_pool_queue_pop(ThreadPool *pool) {
+gb_internal WorkerTask *thread_pool_queue_pop(ThreadPool *pool) {
 	GB_ASSERT(pool->task_queue != nullptr);
 	GB_ASSERT(pool->task_queue != nullptr);
 	WorkerTask *task = pool->task_queue;
 	WorkerTask *task = pool->task_queue;
 	pool->task_queue = task->next;
 	pool->task_queue = task->next;
 	return task;
 	return task;
 }
 }
-void thread_pool_queue_push(ThreadPool *pool, WorkerTask *task) {
+gb_internal void thread_pool_queue_push(ThreadPool *pool, WorkerTask *task) {
 	GB_ASSERT(task != nullptr);
 	GB_ASSERT(task != nullptr);
 	task->next = pool->task_queue;
 	task->next = pool->task_queue;
 	pool->task_queue = task;
 	pool->task_queue = task;
 }
 }
 
 
-bool thread_pool_add_task(ThreadPool *pool, WorkerTaskProc *proc, void *data) {
+gb_internal bool thread_pool_add_task(ThreadPool *pool, WorkerTaskProc *proc, void *data) {
 	GB_ASSERT(proc != nullptr);
 	GB_ASSERT(proc != nullptr);
-	mutex_lock(&pool->mutex);
 	WorkerTask *task = gb_alloc_item(permanent_allocator(), WorkerTask);
 	WorkerTask *task = gb_alloc_item(permanent_allocator(), WorkerTask);
 	if (task == nullptr) {
 	if (task == nullptr) {
-		mutex_unlock(&pool->mutex);
 		GB_PANIC("Out of memory");
 		GB_PANIC("Out of memory");
 		return false;
 		return false;
 	}
 	}
+	task->pool = pool;
 	task->do_work = proc;
 	task->do_work = proc;
 	task->data = data;
 	task->data = data;
 		
 		
+	mutex_lock(&pool->mutex);
 	thread_pool_queue_push(pool, task);
 	thread_pool_queue_push(pool, task);
 	GB_ASSERT(pool->ready >= 0);
 	GB_ASSERT(pool->ready >= 0);
-	pool->ready++;
+	pool->ready.fetch_add(1);
 	condition_broadcast(&pool->task_cond);
 	condition_broadcast(&pool->task_cond);
 	mutex_unlock(&pool->mutex);
 	mutex_unlock(&pool->mutex);
 	return true;
 	return true;
 }	
 }	
 
 
 
 
-void thread_pool_do_task(WorkerTask *task) {
+gb_internal void thread_pool_do_task(WorkerTask *task) {
 	task->do_work(task->data);
 	task->do_work(task->data);
 }
 }
 
 
-void thread_pool_wait(ThreadPool *pool) {
+gb_internal void thread_pool_wait(ThreadPool *pool) {
 	if (pool->threads.count == 0) {
 	if (pool->threads.count == 0) {
 		while (!thread_pool_queue_empty(pool)) {
 		while (!thread_pool_queue_empty(pool)) {
 			thread_pool_do_task(thread_pool_queue_pop(pool));
 			thread_pool_do_task(thread_pool_queue_pop(pool));
-			--pool->ready;
+			pool->ready.fetch_sub(1);
 		}
 		}
 		GB_ASSERT(pool->ready == 0);
 		GB_ASSERT(pool->ready == 0);
 		return;
 		return;
@@ -138,7 +139,7 @@ void thread_pool_wait(ThreadPool *pool) {
 }
 }
 
 
 
 
-THREAD_PROC(thread_pool_thread_proc) {
+gb_internal THREAD_PROC(thread_pool_thread_proc) {
 	ThreadPool *pool = cast(ThreadPool *)thread->user_data;
 	ThreadPool *pool = cast(ThreadPool *)thread->user_data;
 	
 	
 	for (;;) {
 	for (;;) {

+ 100 - 153
src/threading.cpp

@@ -1,6 +1,10 @@
 #if defined(GB_SYSTEM_LINUX)
 #if defined(GB_SYSTEM_LINUX)
 #include <signal.h>
 #include <signal.h>
 #endif
 #endif
+#if defined(GB_SYSTEM_WINDOWS)
+	#pragma warning(push)
+	#pragma warning(disable: 4505)
+#endif
 
 
 struct BlockingMutex;
 struct BlockingMutex;
 struct RecursiveMutex;
 struct RecursiveMutex;
@@ -23,49 +27,46 @@ struct Thread {
 	isize          user_index;
 	isize          user_index;
 	isize volatile return_value;
 	isize volatile return_value;
 
 
-	Semaphore * semaphore;
 	isize       stack_size;
 	isize       stack_size;
 	std::atomic<bool> is_running;
 	std::atomic<bool> is_running;
 };
 };
 
 
 
 
-void mutex_init    (BlockingMutex *m);
-void mutex_destroy (BlockingMutex *m);
-void mutex_lock    (BlockingMutex *m);
-bool mutex_try_lock(BlockingMutex *m);
-void mutex_unlock  (BlockingMutex *m);
-void mutex_init    (RecursiveMutex *m);
-void mutex_destroy (RecursiveMutex *m);
-void mutex_lock    (RecursiveMutex *m);
-bool mutex_try_lock(RecursiveMutex *m);
-void mutex_unlock  (RecursiveMutex *m);
+gb_internal void mutex_init    (BlockingMutex *m);
+gb_internal void mutex_destroy (BlockingMutex *m);
+gb_internal void mutex_lock    (BlockingMutex *m);
+gb_internal bool mutex_try_lock(BlockingMutex *m);
+gb_internal void mutex_unlock  (BlockingMutex *m);
+gb_internal void mutex_init    (RecursiveMutex *m);
+gb_internal void mutex_destroy (RecursiveMutex *m);
+gb_internal void mutex_lock    (RecursiveMutex *m);
+gb_internal bool mutex_try_lock(RecursiveMutex *m);
+gb_internal void mutex_unlock  (RecursiveMutex *m);
 
 
-void semaphore_init   (Semaphore *s);
-void semaphore_destroy(Semaphore *s);
-void semaphore_post   (Semaphore *s, i32 count);
-void semaphore_wait   (Semaphore *s);
-void semaphore_release(Semaphore *s) { semaphore_post(s, 1); }
+gb_internal void semaphore_init   (Semaphore *s);
+gb_internal void semaphore_destroy(Semaphore *s);
+gb_internal void semaphore_post   (Semaphore *s, i32 count);
+gb_internal void semaphore_wait   (Semaphore *s);
+gb_internal void semaphore_release(Semaphore *s) { semaphore_post(s, 1); }
 
 
 
 
-void condition_init(Condition *c);
-void condition_destroy(Condition *c);
-void condition_broadcast(Condition *c);
-void condition_signal(Condition *c);
-void condition_wait(Condition *c, BlockingMutex *m);
-void condition_wait_with_timeout(Condition *c, BlockingMutex *m, u32 timeout_in_ms);
+gb_internal void condition_init(Condition *c);
+gb_internal void condition_destroy(Condition *c);
+gb_internal void condition_broadcast(Condition *c);
+gb_internal void condition_signal(Condition *c);
+gb_internal void condition_wait(Condition *c, BlockingMutex *m);
+gb_internal void condition_wait_with_timeout(Condition *c, BlockingMutex *m, u32 timeout_in_ms);
 
 
-u32  thread_current_id(void);
+gb_internal u32  thread_current_id(void);
 
 
-void thread_init            (Thread *t);
-void thread_destroy         (Thread *t);
-void thread_start           (Thread *t, ThreadProc *proc, void *data);
-void thread_start_with_stack(Thread *t, ThreadProc *proc, void *data, isize stack_size);
-void thread_join            (Thread *t);
-bool thread_is_running      (Thread const *t);
-void thread_set_name        (Thread *t, char const *name);
+gb_internal void thread_init_and_start           (Thread *t, ThreadProc *proc, void *data);
+gb_internal void thread_init_and_start_with_stack(Thread *t, ThreadProc *proc, void *data, isize stack_size);
+gb_internal void thread_join_and_destroy(Thread *t);
+gb_internal bool thread_is_running      (Thread const *t);
+gb_internal void thread_set_name        (Thread *t, char const *name);
 
 
-void yield_thread(void);
-void yield_process(void);
+gb_internal void yield_thread(void);
+gb_internal void yield_process(void);
 
 
 
 
 struct MutexGuard {
 struct MutexGuard {
@@ -106,36 +107,36 @@ struct MutexGuard {
 	struct BlockingMutex {
 	struct BlockingMutex {
 		SRWLOCK srwlock;
 		SRWLOCK srwlock;
 	};
 	};
-	void mutex_init(BlockingMutex *m) {
+	gb_internal void mutex_init(BlockingMutex *m) {
 	}
 	}
-	void mutex_destroy(BlockingMutex *m) {
+	gb_internal void mutex_destroy(BlockingMutex *m) {
 	}
 	}
-	void mutex_lock(BlockingMutex *m) {
+	gb_internal void mutex_lock(BlockingMutex *m) {
 		AcquireSRWLockExclusive(&m->srwlock);
 		AcquireSRWLockExclusive(&m->srwlock);
 	}
 	}
-	bool mutex_try_lock(BlockingMutex *m) {
+	gb_internal bool mutex_try_lock(BlockingMutex *m) {
 		return !!TryAcquireSRWLockExclusive(&m->srwlock);
 		return !!TryAcquireSRWLockExclusive(&m->srwlock);
 	}
 	}
-	void mutex_unlock(BlockingMutex *m) {
+	gb_internal void mutex_unlock(BlockingMutex *m) {
 		ReleaseSRWLockExclusive(&m->srwlock);
 		ReleaseSRWLockExclusive(&m->srwlock);
 	}
 	}
 
 
 	struct RecursiveMutex {
 	struct RecursiveMutex {
 		CRITICAL_SECTION win32_critical_section;
 		CRITICAL_SECTION win32_critical_section;
 	};
 	};
-	void mutex_init(RecursiveMutex *m) {
+	gb_internal void mutex_init(RecursiveMutex *m) {
 		InitializeCriticalSection(&m->win32_critical_section);
 		InitializeCriticalSection(&m->win32_critical_section);
 	}
 	}
-	void mutex_destroy(RecursiveMutex *m) {
+	gb_internal void mutex_destroy(RecursiveMutex *m) {
 		DeleteCriticalSection(&m->win32_critical_section);
 		DeleteCriticalSection(&m->win32_critical_section);
 	}
 	}
-	void mutex_lock(RecursiveMutex *m) {
+	gb_internal void mutex_lock(RecursiveMutex *m) {
 		EnterCriticalSection(&m->win32_critical_section);
 		EnterCriticalSection(&m->win32_critical_section);
 	}
 	}
-	bool mutex_try_lock(RecursiveMutex *m) {
+	gb_internal bool mutex_try_lock(RecursiveMutex *m) {
 		return TryEnterCriticalSection(&m->win32_critical_section) != 0;
 		return TryEnterCriticalSection(&m->win32_critical_section) != 0;
 	}
 	}
-	void mutex_unlock(RecursiveMutex *m) {
+	gb_internal void mutex_unlock(RecursiveMutex *m) {
 		LeaveCriticalSection(&m->win32_critical_section);
 		LeaveCriticalSection(&m->win32_critical_section);
 	}
 	}
 
 
@@ -143,16 +144,16 @@ struct MutexGuard {
 		void *win32_handle;
 		void *win32_handle;
 	};
 	};
 
 
-	void semaphore_init(Semaphore *s) {
+	gb_internal void semaphore_init(Semaphore *s) {
 		s->win32_handle = CreateSemaphoreA(NULL, 0, I32_MAX, NULL);
 		s->win32_handle = CreateSemaphoreA(NULL, 0, I32_MAX, NULL);
 	}
 	}
-	void semaphore_destroy(Semaphore *s) {
+	gb_internal void semaphore_destroy(Semaphore *s) {
 		CloseHandle(s->win32_handle);
 		CloseHandle(s->win32_handle);
 	}
 	}
-	void semaphore_post(Semaphore *s, i32 count) {
+	gb_internal void semaphore_post(Semaphore *s, i32 count) {
 		ReleaseSemaphore(s->win32_handle, count, NULL);
 		ReleaseSemaphore(s->win32_handle, count, NULL);
 	}
 	}
-	void semaphore_wait(Semaphore *s) {
+	gb_internal void semaphore_wait(Semaphore *s) {
 		WaitForSingleObjectEx(s->win32_handle, INFINITE, FALSE);
 		WaitForSingleObjectEx(s->win32_handle, INFINITE, FALSE);
 	}
 	}
 	
 	
@@ -160,20 +161,20 @@ struct MutexGuard {
 		CONDITION_VARIABLE cond;
 		CONDITION_VARIABLE cond;
 	};
 	};
 	
 	
-	void condition_init(Condition *c) {
+	gb_internal void condition_init(Condition *c) {
 	}
 	}
-	void condition_destroy(Condition *c) {	
+	gb_internal void condition_destroy(Condition *c) {
 	}
 	}
-	void condition_broadcast(Condition *c) {
+	gb_internal void condition_broadcast(Condition *c) {
 		WakeAllConditionVariable(&c->cond);
 		WakeAllConditionVariable(&c->cond);
 	}
 	}
-	void condition_signal(Condition *c) {
+	gb_internal void condition_signal(Condition *c) {
 		WakeConditionVariable(&c->cond);
 		WakeConditionVariable(&c->cond);
 	}
 	}
-	void condition_wait(Condition *c, BlockingMutex *m) {
+	gb_internal void condition_wait(Condition *c, BlockingMutex *m) {
 		SleepConditionVariableSRW(&c->cond, &m->srwlock, INFINITE, 0);
 		SleepConditionVariableSRW(&c->cond, &m->srwlock, INFINITE, 0);
 	}
 	}
-	void condition_wait_with_timeout(Condition *c, BlockingMutex *m, u32 timeout_in_ms) {
+	gb_internal void condition_wait_with_timeout(Condition *c, BlockingMutex *m, u32 timeout_in_ms) {
 		SleepConditionVariableSRW(&c->cond, &m->srwlock, timeout_in_ms, 0);
 		SleepConditionVariableSRW(&c->cond, &m->srwlock, timeout_in_ms, 0);
 	}
 	}
 
 
@@ -181,19 +182,19 @@ struct MutexGuard {
 	struct BlockingMutex {
 	struct BlockingMutex {
 		pthread_mutex_t pthread_mutex;
 		pthread_mutex_t pthread_mutex;
 	};
 	};
-	void mutex_init(BlockingMutex *m) {
+	gb_internal void mutex_init(BlockingMutex *m) {
 		pthread_mutex_init(&m->pthread_mutex, nullptr);
 		pthread_mutex_init(&m->pthread_mutex, nullptr);
 	}
 	}
-	void mutex_destroy(BlockingMutex *m) {
+	gb_internal void mutex_destroy(BlockingMutex *m) {
 		pthread_mutex_destroy(&m->pthread_mutex);
 		pthread_mutex_destroy(&m->pthread_mutex);
 	}
 	}
-	void mutex_lock(BlockingMutex *m) {
+	gb_internal void mutex_lock(BlockingMutex *m) {
 		pthread_mutex_lock(&m->pthread_mutex);
 		pthread_mutex_lock(&m->pthread_mutex);
 	}
 	}
-	bool mutex_try_lock(BlockingMutex *m) {
+	gb_internal bool mutex_try_lock(BlockingMutex *m) {
 		return pthread_mutex_trylock(&m->pthread_mutex) == 0;
 		return pthread_mutex_trylock(&m->pthread_mutex) == 0;
 	}
 	}
-	void mutex_unlock(BlockingMutex *m) {
+	gb_internal void mutex_unlock(BlockingMutex *m) {
 		pthread_mutex_unlock(&m->pthread_mutex);
 		pthread_mutex_unlock(&m->pthread_mutex);
 	}
 	}
 
 
@@ -201,21 +202,21 @@ struct MutexGuard {
 		pthread_mutex_t pthread_mutex;
 		pthread_mutex_t pthread_mutex;
 		pthread_mutexattr_t pthread_mutexattr;
 		pthread_mutexattr_t pthread_mutexattr;
 	};
 	};
-	void mutex_init(RecursiveMutex *m) {
+	gb_internal void mutex_init(RecursiveMutex *m) {
 		pthread_mutexattr_init(&m->pthread_mutexattr);
 		pthread_mutexattr_init(&m->pthread_mutexattr);
 		pthread_mutexattr_settype(&m->pthread_mutexattr, PTHREAD_MUTEX_RECURSIVE);
 		pthread_mutexattr_settype(&m->pthread_mutexattr, PTHREAD_MUTEX_RECURSIVE);
 		pthread_mutex_init(&m->pthread_mutex, &m->pthread_mutexattr);
 		pthread_mutex_init(&m->pthread_mutex, &m->pthread_mutexattr);
 	}
 	}
-	void mutex_destroy(RecursiveMutex *m) {
+	gb_internal void mutex_destroy(RecursiveMutex *m) {
 		pthread_mutex_destroy(&m->pthread_mutex);
 		pthread_mutex_destroy(&m->pthread_mutex);
 	}
 	}
-	void mutex_lock(RecursiveMutex *m) {
+	gb_internal void mutex_lock(RecursiveMutex *m) {
 		pthread_mutex_lock(&m->pthread_mutex);
 		pthread_mutex_lock(&m->pthread_mutex);
 	}
 	}
-	bool mutex_try_lock(RecursiveMutex *m) {
+	gb_internal bool mutex_try_lock(RecursiveMutex *m) {
 		return pthread_mutex_trylock(&m->pthread_mutex) == 0;
 		return pthread_mutex_trylock(&m->pthread_mutex) == 0;
 	}
 	}
-	void mutex_unlock(RecursiveMutex *m) {
+	gb_internal void mutex_unlock(RecursiveMutex *m) {
 		pthread_mutex_unlock(&m->pthread_mutex);
 		pthread_mutex_unlock(&m->pthread_mutex);
 	}
 	}
 
 
@@ -224,18 +225,18 @@ struct MutexGuard {
 			semaphore_t osx_handle;
 			semaphore_t osx_handle;
 		};
 		};
 
 
-		void semaphore_init   (Semaphore *s)            { semaphore_create(mach_task_self(), &s->osx_handle, SYNC_POLICY_FIFO, 0); }
-		void semaphore_destroy(Semaphore *s)            { semaphore_destroy(mach_task_self(), s->osx_handle); }
-		void semaphore_post   (Semaphore *s, i32 count) { while (count --> 0) semaphore_signal(s->osx_handle); }
-		void semaphore_wait   (Semaphore *s)            { semaphore_wait(s->osx_handle); }
+		gb_internal void semaphore_init   (Semaphore *s)            { semaphore_create(mach_task_self(), &s->osx_handle, SYNC_POLICY_FIFO, 0); }
+		gb_internal void semaphore_destroy(Semaphore *s)            { semaphore_destroy(mach_task_self(), s->osx_handle); }
+		gb_internal void semaphore_post   (Semaphore *s, i32 count) { while (count --> 0) semaphore_signal(s->osx_handle); }
+		gb_internal void semaphore_wait   (Semaphore *s)            { semaphore_wait(s->osx_handle); }
 	#elif defined(GB_SYSTEM_UNIX)
 	#elif defined(GB_SYSTEM_UNIX)
 		struct Semaphore {
 		struct Semaphore {
 			sem_t unix_handle;
 			sem_t unix_handle;
 		};
 		};
 
 
-		void semaphore_init   (Semaphore *s)            { sem_init(&s->unix_handle, 0, 0); }
-		void semaphore_destroy(Semaphore *s)            { sem_destroy(&s->unix_handle); }
-		void semaphore_post   (Semaphore *s, i32 count) { while (count --> 0) sem_post(&s->unix_handle); }
+		gb_internal void semaphore_init   (Semaphore *s)            { sem_init(&s->unix_handle, 0, 0); }
+		gb_internal void semaphore_destroy(Semaphore *s)            { sem_destroy(&s->unix_handle); }
+		gb_internal void semaphore_post   (Semaphore *s, i32 count) { while (count --> 0) sem_post(&s->unix_handle); }
 		void semaphore_wait   (Semaphore *s)            { int i; do { i = sem_wait(&s->unix_handle); } while (i == -1 && errno == EINTR); }
 		void semaphore_wait   (Semaphore *s)            { int i; do { i = sem_wait(&s->unix_handle); } while (i == -1 && errno == EINTR); }
 	#else
 	#else
 	#error Implement Semaphore for this platform
 	#error Implement Semaphore for this platform
@@ -246,22 +247,22 @@ struct MutexGuard {
 		pthread_cond_t pthread_cond;
 		pthread_cond_t pthread_cond;
 	};
 	};
 	
 	
-	void condition_init(Condition *c) {
+	gb_internal void condition_init(Condition *c) {
 		pthread_cond_init(&c->pthread_cond, NULL);
 		pthread_cond_init(&c->pthread_cond, NULL);
 	}
 	}
-	void condition_destroy(Condition *c) {	
+	gb_internal void condition_destroy(Condition *c) {
 		pthread_cond_destroy(&c->pthread_cond);
 		pthread_cond_destroy(&c->pthread_cond);
 	}
 	}
-	void condition_broadcast(Condition *c) {
+	gb_internal void condition_broadcast(Condition *c) {
 		pthread_cond_broadcast(&c->pthread_cond);
 		pthread_cond_broadcast(&c->pthread_cond);
 	}
 	}
-	void condition_signal(Condition *c) {
+	gb_internal void condition_signal(Condition *c) {
 		pthread_cond_signal(&c->pthread_cond);
 		pthread_cond_signal(&c->pthread_cond);
 	}
 	}
-	void condition_wait(Condition *c, BlockingMutex *m) {
+	gb_internal void condition_wait(Condition *c, BlockingMutex *m) {
 		pthread_cond_wait(&c->pthread_cond, &m->pthread_mutex);
 		pthread_cond_wait(&c->pthread_cond, &m->pthread_mutex);
 	}
 	}
-	void condition_wait_with_timeout(Condition *c, BlockingMutex *m, u32 timeout_in_ms) {
+	gb_internal void condition_wait_with_timeout(Condition *c, BlockingMutex *m, u32 timeout_in_ms) {
 		struct timespec abstime = {};
 		struct timespec abstime = {};
 		abstime.tv_sec = timeout_in_ms/1000;
 		abstime.tv_sec = timeout_in_ms/1000;
 		abstime.tv_nsec = cast(long)(timeout_in_ms%1000)*1e6;
 		abstime.tv_nsec = cast(long)(timeout_in_ms%1000)*1e6;
@@ -269,51 +270,9 @@ struct MutexGuard {
 		
 		
 	}
 	}
 #endif
 #endif
-	
-	
-struct Barrier {
-	BlockingMutex mutex;
-	Condition cond;
-	isize index;
-	isize generation_id;
-	isize thread_count;	
-};
-
-void barrier_init(Barrier *b, isize thread_count) {
-	mutex_init(&b->mutex);
-	condition_init(&b->cond);
-	b->index = 0;
-	b->generation_id = 0;
-	b->thread_count = 0;
-}
-
-void barrier_destroy(Barrier *b) {
-	condition_destroy(&b->cond);
-	mutex_destroy(&b->mutex);
-}
-
-// Returns true if it is the leader
-bool barrier_wait(Barrier *b) {
-	mutex_lock(&b->mutex);
-	defer (mutex_unlock(&b->mutex));
-	isize local_gen = b->generation_id;
-	b->index += 1;
-	if (b->index < b->thread_count) {
-		while (local_gen == b->generation_id && b->index < b->thread_count) {
-			condition_wait(&b->cond, &b->mutex);
-		}
-		return false;
-	}
-	b->index = 0;
-	b->generation_id += 1;
-	condition_broadcast(&b->cond);
-	return true;
-}
-
 
 
 
 
-
-u32 thread_current_id(void) {
+gb_internal u32 thread_current_id(void) {
 	u32 thread_id;
 	u32 thread_id;
 #if defined(GB_SYSTEM_WINDOWS)
 #if defined(GB_SYSTEM_WINDOWS)
 	#if defined(GB_ARCH_32_BIT) && defined(GB_CPU_X86)
 	#if defined(GB_ARCH_32_BIT) && defined(GB_CPU_X86)
@@ -340,7 +299,7 @@ u32 thread_current_id(void) {
 }
 }
 
 
 
 
-gb_inline void yield_thread(void) {
+gb_internal gb_inline void yield_thread(void) {
 #if defined(GB_SYSTEM_WINDOWS)
 #if defined(GB_SYSTEM_WINDOWS)
 	_mm_pause();
 	_mm_pause();
 #elif defined(GB_SYSTEM_OSX)
 #elif defined(GB_SYSTEM_OSX)
@@ -358,7 +317,7 @@ gb_inline void yield_thread(void) {
 #endif
 #endif
 }
 }
 
 
-gb_inline void yield(void) {
+gb_internal gb_inline void yield(void) {
 #if defined(GB_SYSTEM_WINDOWS)
 #if defined(GB_SYSTEM_WINDOWS)
 	YieldProcessor();
 	YieldProcessor();
 #else
 #else
@@ -366,39 +325,19 @@ gb_inline void yield(void) {
 #endif
 #endif
 }
 }
 
 
-
-void thread_init(Thread *t) {
-	gb_zero_item(t);
-#if defined(GB_SYSTEM_WINDOWS)
-	t->win32_handle = INVALID_HANDLE_VALUE;
-#else
-	t->posix_handle = 0;
-#endif
-	t->semaphore = gb_alloc_item(heap_allocator(), Semaphore);
-	semaphore_init(t->semaphore);
-}
-
-void thread_destroy(Thread *t) {
-	thread_join(t);
-	semaphore_destroy(t->semaphore);
-	gb_free(heap_allocator(), t->semaphore);
-}
-
-
-void gb__thread_run(Thread *t) {
-	semaphore_release(t->semaphore);
+gb_internal void private__thread_run(Thread *t) {
 	t->return_value = t->proc(t);
 	t->return_value = t->proc(t);
 }
 }
 
 
 #if defined(GB_SYSTEM_WINDOWS)
 #if defined(GB_SYSTEM_WINDOWS)
-	DWORD __stdcall internal_thread_proc(void *arg) {
+	gb_internal DWORD __stdcall internal_thread_proc(void *arg) {
 		Thread *t = cast(Thread *)arg;
 		Thread *t = cast(Thread *)arg;
 		t->is_running.store(true);
 		t->is_running.store(true);
-		gb__thread_run(t);
+		private__thread_run(t);
 		return 0;
 		return 0;
 	}
 	}
 #else
 #else
-	void *internal_thread_proc(void *arg) {
+	gb_internal void *internal_thread_proc(void *arg) {
 	#if (GB_SYSTEM_LINUX)
 	#if (GB_SYSTEM_LINUX)
 		// NOTE: Don't permit any signal delivery to threads on Linux.
 		// NOTE: Don't permit any signal delivery to threads on Linux.
 		sigset_t mask = {};
 		sigset_t mask = {};
@@ -408,14 +347,20 @@ void gb__thread_run(Thread *t) {
 		
 		
 		Thread *t = cast(Thread *)arg;
 		Thread *t = cast(Thread *)arg;
 		t->is_running.store(true);
 		t->is_running.store(true);
-		gb__thread_run(t);
+		private__thread_run(t);
 		return NULL;
 		return NULL;
 	}
 	}
 #endif
 #endif
 
 
-void thread_start(Thread *t, ThreadProc *proc, void *user_data) { thread_start_with_stack(t, proc, user_data, 0); }
+gb_internal void thread_init_and_start(Thread *t, ThreadProc *proc, void *user_data) { thread_init_and_start_with_stack(t, proc, user_data, 0); }
 
 
-void thread_start_with_stack(Thread *t, ThreadProc *proc, void *user_data, isize stack_size) {
+gb_internal void thread_init_and_start_with_stack(Thread *t, ThreadProc *proc, void *user_data, isize stack_size) {
+	gb_zero_item(t);
+#if defined(GB_SYSTEM_WINDOWS)
+	t->win32_handle = INVALID_HANDLE_VALUE;
+#else
+	t->posix_handle = 0;
+#endif
 	GB_ASSERT(!t->is_running.load());
 	GB_ASSERT(!t->is_running.load());
 	GB_ASSERT(proc != NULL);
 	GB_ASSERT(proc != NULL);
 	t->proc = proc;
 	t->proc = proc;
@@ -429,19 +374,17 @@ void thread_start_with_stack(Thread *t, ThreadProc *proc, void *user_data, isize
 	{
 	{
 		pthread_attr_t attr;
 		pthread_attr_t attr;
 		pthread_attr_init(&attr);
 		pthread_attr_init(&attr);
+		defer (pthread_attr_destroy(&attr));
 		pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
 		pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
 		if (stack_size != 0) {
 		if (stack_size != 0) {
 			pthread_attr_setstacksize(&attr, stack_size);
 			pthread_attr_setstacksize(&attr, stack_size);
 		}
 		}
 		pthread_create(&t->posix_handle, &attr, internal_thread_proc, t);
 		pthread_create(&t->posix_handle, &attr, internal_thread_proc, t);
-		pthread_attr_destroy(&attr);
 	}
 	}
 #endif
 #endif
-
-	semaphore_wait(t->semaphore);
 }
 }
 
 
-void thread_join(Thread *t) {
+gb_internal void thread_join_and_destroy(Thread *t) {
 	if (!t->is_running.load()) {
 	if (!t->is_running.load()) {
 		return;
 		return;
 	}
 	}
@@ -457,9 +400,9 @@ void thread_join(Thread *t) {
 	t->is_running.store(false);
 	t->is_running.store(false);
 }
 }
 
 
-bool thread_is_running(Thread const *t) { return t->is_running.load(); }
+gb_internal bool thread_is_running(Thread const *t) { return t->is_running.load(); }
 
 
-void thread_set_name(Thread *t, char const *name) {
+gb_internal void thread_set_name(Thread *t, char const *name) {
 #if defined(GB_COMPILER_MSVC)
 #if defined(GB_COMPILER_MSVC)
 	#pragma pack(push, 8)
 	#pragma pack(push, 8)
 		typedef struct {
 		typedef struct {
@@ -494,3 +437,7 @@ void thread_set_name(Thread *t, char const *name) {
 #endif
 #endif
 }
 }
 
 
+
+#if defined(GB_SYSTEM_WINDOWS)
+	#pragma warning(pop)
+#endif

+ 18 - 18
src/timings.cpp

@@ -13,13 +13,13 @@ struct Timings {
 
 
 
 
 #if defined(GB_SYSTEM_WINDOWS)
 #if defined(GB_SYSTEM_WINDOWS)
-u64 win32_time_stamp_time_now(void) {
+gb_internal u64 win32_time_stamp_time_now(void) {
 	LARGE_INTEGER counter;
 	LARGE_INTEGER counter;
 	QueryPerformanceCounter(&counter);
 	QueryPerformanceCounter(&counter);
 	return counter.QuadPart;
 	return counter.QuadPart;
 }
 }
 
 
-u64 win32_time_stamp__freq(void) {
+gb_internal u64 win32_time_stamp__freq(void) {
 	gb_local_persist LARGE_INTEGER win32_perf_count_freq = {0};
 	gb_local_persist LARGE_INTEGER win32_perf_count_freq = {0};
 	if (!win32_perf_count_freq.QuadPart) {
 	if (!win32_perf_count_freq.QuadPart) {
 		QueryPerformanceFrequency(&win32_perf_count_freq);
 		QueryPerformanceFrequency(&win32_perf_count_freq);
@@ -33,11 +33,11 @@ u64 win32_time_stamp__freq(void) {
 
 
 #include <mach/mach_time.h>
 #include <mach/mach_time.h>
 
 
-u64 osx_time_stamp_time_now(void) {
+gb_internal u64 osx_time_stamp_time_now(void) {
 	return mach_absolute_time();
 	return mach_absolute_time();
 }
 }
 
 
-u64 osx_time_stamp__freq(void) {
+gb_internal u64 osx_time_stamp__freq(void) {
 	mach_timebase_info_data_t data;
 	mach_timebase_info_data_t data;
 	data.numer = 0;
 	data.numer = 0;
 	data.denom = 0;
 	data.denom = 0;
@@ -55,14 +55,14 @@ u64 osx_time_stamp__freq(void) {
 
 
 #include <time.h>
 #include <time.h>
 
 
-u64 unix_time_stamp_time_now(void) {
+gb_internal u64 unix_time_stamp_time_now(void) {
 	struct timespec ts;
 	struct timespec ts;
 	clock_gettime(CLOCK_MONOTONIC, &ts);
 	clock_gettime(CLOCK_MONOTONIC, &ts);
 
 
 	return (ts.tv_sec * 1000000000) + ts.tv_nsec;
 	return (ts.tv_sec * 1000000000) + ts.tv_nsec;
 }
 }
 
 
-u64 unix_time_stamp__freq(void) {
+gb_internal u64 unix_time_stamp__freq(void) {
 	gb_local_persist u64 freq = 0;
 	gb_local_persist u64 freq = 0;
 
 
 	if (freq == 0) {
 	if (freq == 0) {
@@ -80,7 +80,7 @@ u64 unix_time_stamp__freq(void) {
 #error Implement system
 #error Implement system
 #endif
 #endif
 
 
-u64 time_stamp_time_now(void) {
+gb_internal u64 time_stamp_time_now(void) {
 #if defined(GB_SYSTEM_WINDOWS)
 #if defined(GB_SYSTEM_WINDOWS)
 	return win32_time_stamp_time_now();
 	return win32_time_stamp_time_now();
 #elif defined(GB_SYSTEM_OSX)
 #elif defined(GB_SYSTEM_OSX)
@@ -92,7 +92,7 @@ u64 time_stamp_time_now(void) {
 #endif
 #endif
 }
 }
 
 
-u64 time_stamp__freq(void) {
+gb_internal u64 time_stamp__freq(void) {
 #if defined(GB_SYSTEM_WINDOWS)
 #if defined(GB_SYSTEM_WINDOWS)
 	return win32_time_stamp__freq();
 	return win32_time_stamp__freq();
 #elif defined(GB_SYSTEM_OSX)
 #elif defined(GB_SYSTEM_OSX)
@@ -104,44 +104,44 @@ u64 time_stamp__freq(void) {
 #endif
 #endif
 }
 }
 
 
-TimeStamp make_time_stamp(String const &label) {
+gb_internal TimeStamp make_time_stamp(String const &label) {
 	TimeStamp ts = {0};
 	TimeStamp ts = {0};
 	ts.start = time_stamp_time_now();
 	ts.start = time_stamp_time_now();
 	ts.label = label;
 	ts.label = label;
 	return ts;
 	return ts;
 }
 }
 
 
-void timings_init(Timings *t, String const &label, isize buffer_size) {
+gb_internal void timings_init(Timings *t, String const &label, isize buffer_size) {
 	array_init(&t->sections, heap_allocator(), 0, 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();
 }
 }
 
 
-void timings_destroy(Timings *t) {
+gb_internal void timings_destroy(Timings *t) {
 	array_free(&t->sections);
 	array_free(&t->sections);
 }
 }
 
 
-void timings__stop_current_section(Timings *t) {
+gb_internal void timings__stop_current_section(Timings *t) {
 	if (t->sections.count > 0) {
 	if (t->sections.count > 0) {
 		t->sections[t->sections.count-1].finish = time_stamp_time_now();
 		t->sections[t->sections.count-1].finish = time_stamp_time_now();
 	}
 	}
 }
 }
 
 
-void timings_start_section(Timings *t, String const &label) {
+gb_internal void timings_start_section(Timings *t, String const &label) {
 	timings__stop_current_section(t);
 	timings__stop_current_section(t);
 	array_add(&t->sections, make_time_stamp(label));
 	array_add(&t->sections, make_time_stamp(label));
 }
 }
 
 
-f64 time_stamp_as_s(TimeStamp const &ts, u64 freq) {
+gb_internal f64 time_stamp_as_s(TimeStamp const &ts, u64 freq) {
 	GB_ASSERT_MSG(ts.finish >= ts.start, "time_stamp_as_ms - %.*s", LIT(ts.label));
 	GB_ASSERT_MSG(ts.finish >= ts.start, "time_stamp_as_ms - %.*s", LIT(ts.label));
 	return cast(f64)(ts.finish - ts.start) / cast(f64)freq;
 	return cast(f64)(ts.finish - ts.start) / cast(f64)freq;
 }
 }
 
 
-f64 time_stamp_as_ms(TimeStamp const &ts, u64 freq) {
+gb_internal f64 time_stamp_as_ms(TimeStamp const &ts, u64 freq) {
 	return 1000.0*time_stamp_as_s(ts, freq);
 	return 1000.0*time_stamp_as_s(ts, freq);
 }
 }
 
 
-f64 time_stamp_as_us(TimeStamp const &ts, u64 freq) {
+gb_internal f64 time_stamp_as_us(TimeStamp const &ts, u64 freq) {
 	return 1000000.0*time_stamp_as_s(ts, freq);
 	return 1000000.0*time_stamp_as_s(ts, freq);
 }
 }
 
 
@@ -160,7 +160,7 @@ enum TimingUnit {
 
 
 char const *timing_unit_strings[TimingUnit_COUNT] = {"s", "ms", "us"};
 char const *timing_unit_strings[TimingUnit_COUNT] = {"s", "ms", "us"};
 
 
-f64 time_stamp(TimeStamp const &ts, u64 freq, TimingUnit unit) {
+gb_internal f64 time_stamp(TimeStamp const &ts, u64 freq, TimingUnit unit) {
 	switch (unit) {
 	switch (unit) {
 	case TimingUnit_Millisecond: return time_stamp_as_ms(ts, freq);
 	case TimingUnit_Millisecond: return time_stamp_as_ms(ts, freq);
 	case TimingUnit_Microsecond: return time_stamp_as_us(ts, freq);
 	case TimingUnit_Microsecond: return time_stamp_as_us(ts, freq);
@@ -169,7 +169,7 @@ f64 time_stamp(TimeStamp const &ts, u64 freq, TimingUnit unit) {
 	}
 	}
 }
 }
 
 
-void timings_print_all(Timings *t, TimingUnit unit = TimingUnit_Millisecond, bool timings_are_finalized = false) {
+gb_internal void timings_print_all(Timings *t, TimingUnit unit = TimingUnit_Millisecond, bool timings_are_finalized = false) {
 	isize const SPACES_LEN = 256;
 	isize const SPACES_LEN = 256;
 	char SPACES[SPACES_LEN+1] = {0};
 	char SPACES[SPACES_LEN+1] = {0};
 	gb_memset(SPACES, ' ', SPACES_LEN);
 	gb_memset(SPACES, ' ', SPACES_LEN);

+ 35 - 35
src/tokenizer.cpp

@@ -151,10 +151,10 @@ gb_global isize max_keyword_size = 11;
 gb_global bool keyword_indices[16] = {};
 gb_global bool keyword_indices[16] = {};
 
 
 
 
-gb_inline u32 keyword_hash(u8 const *text, isize len) {
+gb_internal gb_inline u32 keyword_hash(u8 const *text, isize len) {
 	return fnv32a(text, len);
 	return fnv32a(text, len);
 }
 }
-void add_keyword_hash_entry(String const &s, TokenKind kind) {
+gb_internal void add_keyword_hash_entry(String const &s, TokenKind kind) {
 	max_keyword_size = gb_max(max_keyword_size, s.len);
 	max_keyword_size = gb_max(max_keyword_size, s.len);
 
 
 	keyword_indices[s.len] = true;
 	keyword_indices[s.len] = true;
@@ -169,7 +169,7 @@ void add_keyword_hash_entry(String const &s, TokenKind kind) {
 	entry->kind = kind;
 	entry->kind = kind;
 	entry->text = s;
 	entry->text = s;
 }
 }
-void init_keyword_hash_table(void) {
+gb_internal void init_keyword_hash_table(void) {
 	for (i32 kind = Token__KeywordBegin+1; kind < Token__KeywordEnd; kind++) {
 	for (i32 kind = Token__KeywordBegin+1; kind < Token__KeywordEnd; kind++) {
 		add_keyword_hash_entry(token_strings[kind], cast(TokenKind)kind);
 		add_keyword_hash_entry(token_strings[kind], cast(TokenKind)kind);
 	}
 	}
@@ -191,8 +191,8 @@ void init_keyword_hash_table(void) {
 gb_global Array<String>           global_file_path_strings; // index is file id
 gb_global Array<String>           global_file_path_strings; // index is file id
 gb_global Array<struct AstFile *> global_files; // index is file id
 gb_global Array<struct AstFile *> global_files; // index is file id
 
 
-String   get_file_path_string(i32 index);
-struct AstFile *thread_safe_get_ast_file_from_id(i32 index);
+gb_internal String   get_file_path_string(i32 index);
+gb_internal struct AstFile *thread_safe_get_ast_file_from_id(i32 index);
 
 
 struct TokenPos {
 struct TokenPos {
 	i32 file_id;
 	i32 file_id;
@@ -201,7 +201,7 @@ struct TokenPos {
 	i32 column; // starting at 1
 	i32 column; // starting at 1
 };
 };
 
 
-i32 token_pos_cmp(TokenPos const &a, TokenPos const &b) {
+gb_internal i32 token_pos_cmp(TokenPos const &a, TokenPos const &b) {
 	if (a.offset != b.offset) {
 	if (a.offset != b.offset) {
 		return (a.offset < b.offset) ? -1 : +1;
 		return (a.offset < b.offset) ? -1 : +1;
 	}
 	}
@@ -214,12 +214,12 @@ i32 token_pos_cmp(TokenPos const &a, TokenPos const &b) {
 	return string_compare(get_file_path_string(a.file_id), get_file_path_string(b.file_id));
 	return string_compare(get_file_path_string(a.file_id), get_file_path_string(b.file_id));
 }
 }
 
 
-bool operator==(TokenPos const &a, TokenPos const &b) { return token_pos_cmp(a, b) == 0; }
-bool operator!=(TokenPos const &a, TokenPos const &b) { return token_pos_cmp(a, b) != 0; }
-bool operator< (TokenPos const &a, TokenPos const &b) { return token_pos_cmp(a, b) <  0; }
-bool operator<=(TokenPos const &a, TokenPos const &b) { return token_pos_cmp(a, b) <= 0; }
-bool operator> (TokenPos const &a, TokenPos const &b) { return token_pos_cmp(a, b) >  0; }
-bool operator>=(TokenPos const &a, TokenPos const &b) { return token_pos_cmp(a, b) >= 0; }
+gb_internal gb_inline bool operator==(TokenPos const &a, TokenPos const &b) { return token_pos_cmp(a, b) == 0; }
+gb_internal gb_inline bool operator!=(TokenPos const &a, TokenPos const &b) { return token_pos_cmp(a, b) != 0; }
+gb_internal gb_inline bool operator< (TokenPos const &a, TokenPos const &b) { return token_pos_cmp(a, b) <  0; }
+gb_internal gb_inline bool operator<=(TokenPos const &a, TokenPos const &b) { return token_pos_cmp(a, b) <= 0; }
+gb_internal gb_inline bool operator> (TokenPos const &a, TokenPos const &b) { return token_pos_cmp(a, b) >  0; }
+gb_internal gb_inline bool operator>=(TokenPos const &a, TokenPos const &b) { return token_pos_cmp(a, b) >= 0; }
 
 
 
 
 TokenPos token_pos_add_column(TokenPos pos) {
 TokenPos token_pos_add_column(TokenPos pos) {
@@ -243,36 +243,36 @@ struct Token {
 Token empty_token = {Token_Invalid};
 Token empty_token = {Token_Invalid};
 Token blank_token = {Token_Ident, 0, {cast(u8 *)"_", 1}};
 Token blank_token = {Token_Ident, 0, {cast(u8 *)"_", 1}};
 
 
-Token make_token_ident(String s) {
+gb_internal Token make_token_ident(String s) {
 	Token t = {Token_Ident, 0, s};
 	Token t = {Token_Ident, 0, s};
 	return t;
 	return t;
 }
 }
-Token make_token_ident(char const *s) {
+gb_internal Token make_token_ident(char const *s) {
 	Token t = {Token_Ident, 0, make_string_c(s)};
 	Token t = {Token_Ident, 0, make_string_c(s)};
 	return t;
 	return t;
 }
 }
 
 
-bool token_is_newline(Token const &tok) {
+gb_internal bool token_is_newline(Token const &tok) {
 	return tok.kind == Token_Semicolon && tok.string == "\n";
 	return tok.kind == Token_Semicolon && tok.string == "\n";
 }
 }
 
 
-gb_inline bool token_is_literal(TokenKind t) {
+gb_internal gb_inline bool token_is_literal(TokenKind t) {
 	return gb_is_between(t, Token__LiteralBegin+1, Token__LiteralEnd-1);
 	return gb_is_between(t, Token__LiteralBegin+1, Token__LiteralEnd-1);
 }
 }
-gb_inline bool token_is_operator(TokenKind t) {
+gb_internal gb_inline bool token_is_operator(TokenKind t) {
 	return gb_is_between(t, Token__OperatorBegin+1, Token__OperatorEnd-1);
 	return gb_is_between(t, Token__OperatorBegin+1, Token__OperatorEnd-1);
 }
 }
-gb_inline bool token_is_keyword(TokenKind t) {
+gb_internal gb_inline bool token_is_keyword(TokenKind t) {
 	return gb_is_between(t, Token__KeywordBegin+1, Token__KeywordEnd-1);
 	return gb_is_between(t, Token__KeywordBegin+1, Token__KeywordEnd-1);
 }
 }
-gb_inline bool token_is_comparison(TokenKind t) {
+gb_internal gb_inline bool token_is_comparison(TokenKind t) {
 	return gb_is_between(t, Token__ComparisonBegin+1, Token__ComparisonEnd-1);
 	return gb_is_between(t, Token__ComparisonBegin+1, Token__ComparisonEnd-1);
 }
 }
-gb_inline bool token_is_shift(TokenKind t) {
+gb_internal gb_inline bool token_is_shift(TokenKind t) {
 	return t == Token_Shl || t == Token_Shr;
 	return t == Token_Shl || t == Token_Shr;
 }
 }
 
 
-gb_inline void print_token(Token t) { gb_printf("%.*s\n", LIT(t.string)); }
+gb_internal gb_inline void print_token(Token t) { gb_printf("%.*s\n", LIT(t.string)); }
 
 
 #include "error.cpp"
 #include "error.cpp"
 
 
@@ -309,7 +309,7 @@ struct Tokenizer {
 };
 };
 
 
 
 
-void tokenizer_err(Tokenizer *t, char const *msg, ...) {
+gb_internal void tokenizer_err(Tokenizer *t, char const *msg, ...) {
 	va_list va;
 	va_list va;
 	i32 column = t->column_minus_one+1;
 	i32 column = t->column_minus_one+1;
 	if (column < 1) {
 	if (column < 1) {
@@ -328,7 +328,7 @@ void tokenizer_err(Tokenizer *t, char const *msg, ...) {
 	t->error_count++;
 	t->error_count++;
 }
 }
 
 
-void tokenizer_err(Tokenizer *t, TokenPos const &pos, char const *msg, ...) {
+gb_internal void tokenizer_err(Tokenizer *t, TokenPos const &pos, char const *msg, ...) {
 	va_list va;
 	va_list va;
 	i32 column = t->column_minus_one+1;
 	i32 column = t->column_minus_one+1;
 	if (column < 1) {
 	if (column < 1) {
@@ -342,7 +342,7 @@ void tokenizer_err(Tokenizer *t, TokenPos const &pos, char const *msg, ...) {
 	t->error_count++;
 	t->error_count++;
 }
 }
 
 
-void advance_to_next_rune(Tokenizer *t) {
+gb_internal void advance_to_next_rune(Tokenizer *t) {
 	if (t->curr_rune == '\n') {
 	if (t->curr_rune == '\n') {
 		t->column_minus_one = -1;
 		t->column_minus_one = -1;
 		t->line_count++;
 		t->line_count++;
@@ -372,7 +372,7 @@ void advance_to_next_rune(Tokenizer *t) {
 	}
 	}
 }
 }
 
 
-void init_tokenizer_with_data(Tokenizer *t, String const &fullpath, void const *data, isize size) {
+gb_internal void init_tokenizer_with_data(Tokenizer *t, String const &fullpath, void const *data, isize size) {
 	t->fullpath = fullpath;
 	t->fullpath = fullpath;
 	t->line_count = 1;
 	t->line_count = 1;
 
 
@@ -386,7 +386,7 @@ void init_tokenizer_with_data(Tokenizer *t, String const &fullpath, void const *
 	}
 	}
 }
 }
 
 
-TokenizerInitError loaded_file_error_map_to_tokenizer[LoadedFile_COUNT] = {
+gb_global TokenizerInitError loaded_file_error_map_to_tokenizer[LoadedFile_COUNT] = {
 	TokenizerInit_None,         /*LoadedFile_None*/
 	TokenizerInit_None,         /*LoadedFile_None*/
 	TokenizerInit_Empty,        /*LoadedFile_Empty*/
 	TokenizerInit_Empty,        /*LoadedFile_Empty*/
 	TokenizerInit_FileTooLarge, /*LoadedFile_FileTooLarge*/
 	TokenizerInit_FileTooLarge, /*LoadedFile_FileTooLarge*/
@@ -395,7 +395,7 @@ TokenizerInitError loaded_file_error_map_to_tokenizer[LoadedFile_COUNT] = {
 	TokenizerInit_Permission,   /*LoadedFile_Permission*/
 	TokenizerInit_Permission,   /*LoadedFile_Permission*/
 };
 };
 
 
-TokenizerInitError init_tokenizer_from_fullpath(Tokenizer *t, String const &fullpath, bool copy_file_contents) {
+gb_internal TokenizerInitError init_tokenizer_from_fullpath(Tokenizer *t, String const &fullpath, bool copy_file_contents) {
 	LoadedFileError file_err = load_file_32(
 	LoadedFileError file_err = load_file_32(
 		alloc_cstring(temporary_allocator(), fullpath), 
 		alloc_cstring(temporary_allocator(), fullpath), 
 		&t->loaded_file,
 		&t->loaded_file,
@@ -416,7 +416,7 @@ TokenizerInitError init_tokenizer_from_fullpath(Tokenizer *t, String const &full
 	return err;
 	return err;
 }
 }
 
 
-gb_inline i32 digit_value(Rune r) {
+gb_internal gb_inline i32 digit_value(Rune r) {
 	switch (r) {
 	switch (r) {
 	case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
 	case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
 		return r - '0';
 		return r - '0';
@@ -428,20 +428,20 @@ gb_inline i32 digit_value(Rune r) {
 	return 16; // NOTE(bill): Larger than highest possible
 	return 16; // NOTE(bill): Larger than highest possible
 }
 }
 
 
-gb_inline void scan_mantissa(Tokenizer *t, i32 base) {
+gb_internal gb_inline void scan_mantissa(Tokenizer *t, i32 base) {
 	while (digit_value(t->curr_rune) < base || t->curr_rune == '_') {
 	while (digit_value(t->curr_rune) < base || t->curr_rune == '_') {
 		advance_to_next_rune(t);
 		advance_to_next_rune(t);
 	}
 	}
 }
 }
 
 
-u8 peek_byte(Tokenizer *t, isize offset=0) {
+gb_internal u8 peek_byte(Tokenizer *t, isize offset=0) {
 	if (t->read_curr+offset < t->end) {
 	if (t->read_curr+offset < t->end) {
 		return t->read_curr[offset];
 		return t->read_curr[offset];
 	}
 	}
 	return 0;
 	return 0;
 }
 }
 
 
-void scan_number_to_token(Tokenizer *t, Token *token, bool seen_decimal_point) {
+gb_internal void scan_number_to_token(Tokenizer *t, Token *token, bool seen_decimal_point) {
 	token->kind = Token_Integer;
 	token->kind = Token_Integer;
 	token->string = {t->curr, 1};
 	token->string = {t->curr, 1};
 	token->pos.file_id = t->curr_file_id;
 	token->pos.file_id = t->curr_file_id;
@@ -566,7 +566,7 @@ end:
 }
 }
 
 
 
 
-bool scan_escape(Tokenizer *t) {
+gb_internal bool scan_escape(Tokenizer *t) {
 	isize len = 0;
 	isize len = 0;
 	u32 base = 0, max = 0, x = 0;
 	u32 base = 0, max = 0, x = 0;
 
 
@@ -633,13 +633,13 @@ bool scan_escape(Tokenizer *t) {
 }
 }
 
 
 
 
-gb_inline void tokenizer_skip_line(Tokenizer *t) {
+gb_internal gb_inline void tokenizer_skip_line(Tokenizer *t) {
 	while (t->curr_rune != '\n' && t->curr_rune != GB_RUNE_EOF) {
 	while (t->curr_rune != '\n' && t->curr_rune != GB_RUNE_EOF) {
 		advance_to_next_rune(t);
 		advance_to_next_rune(t);
 	}
 	}
 }
 }
 
 
-gb_inline void tokenizer_skip_whitespace(Tokenizer *t, bool on_newline) {
+gb_internal gb_inline void tokenizer_skip_whitespace(Tokenizer *t, bool on_newline) {
 	if (on_newline) {
 	if (on_newline) {
 		for (;;) {
 		for (;;) {
 			switch (t->curr_rune) {
 			switch (t->curr_rune) {
@@ -666,7 +666,7 @@ gb_inline void tokenizer_skip_whitespace(Tokenizer *t, bool on_newline) {
 	}
 	}
 }
 }
 
 
-void tokenizer_get_token(Tokenizer *t, Token *token, int repeat=0) {
+gb_internal void tokenizer_get_token(Tokenizer *t, Token *token, int repeat=0) {
 	tokenizer_skip_whitespace(t, t->insert_semicolon);
 	tokenizer_skip_whitespace(t, t->insert_semicolon);
 
 
 	token->kind = Token_Invalid;
 	token->kind = Token_Invalid;

File diff suppressed because it is too large
+ 145 - 193
src/types.cpp


+ 5 - 5
src/unicode.cpp

@@ -7,7 +7,7 @@ extern "C" {
 #pragma warning(pop)
 #pragma warning(pop)
 
 
 
 
-bool rune_is_letter(Rune r) {
+gb_internal bool rune_is_letter(Rune r) {
 	if (r < 0x80) {
 	if (r < 0x80) {
 		if (r == '_') {
 		if (r == '_') {
 			return true;
 			return true;
@@ -25,14 +25,14 @@ bool rune_is_letter(Rune r) {
 	return false;
 	return false;
 }
 }
 
 
-bool rune_is_digit(Rune r) {
+gb_internal bool rune_is_digit(Rune r) {
 	if (r < 0x80) {
 	if (r < 0x80) {
 		return (cast(u32)r - '0') < 10;
 		return (cast(u32)r - '0') < 10;
 	}
 	}
 	return utf8proc_category(r) == UTF8PROC_CATEGORY_ND;
 	return utf8proc_category(r) == UTF8PROC_CATEGORY_ND;
 }
 }
 
 
-bool rune_is_letter_or_digit(Rune r) {
+gb_internal bool rune_is_letter_or_digit(Rune r) {
 	if (r < 0x80) {
 	if (r < 0x80) {
 		if (r == '_') {
 		if (r == '_') {
 			return true;
 			return true;
@@ -55,7 +55,7 @@ bool rune_is_letter_or_digit(Rune r) {
 	return false;
 	return false;
 }
 }
 
 
-bool rune_is_whitespace(Rune r) {
+gb_internal bool rune_is_whitespace(Rune r) {
 	switch (r) {
 	switch (r) {
 	case ' ':
 	case ' ':
 	case '\t':
 	case '\t':
@@ -99,7 +99,7 @@ gb_global Utf8AcceptRange const global__utf8_accept_ranges[] = {
 };
 };
 
 
 
 
-isize utf8_decode(u8 const *str, isize str_len, Rune *codepoint_out) {
+gb_internal isize utf8_decode(u8 const *str, isize str_len, Rune *codepoint_out) {
 	isize width = 0;
 	isize width = 0;
 	Rune codepoint = GB_RUNE_INVALID;
 	Rune codepoint = GB_RUNE_INVALID;
 
 

Some files were not shown because too many files changed in this diff