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

Compiler Improvements for 2022-12
This commit is contained in:
gingerBill
2023-01-01 13:26:43 +00:00
committed by GitHub
53 changed files with 3118 additions and 4602 deletions
+1
View File
@@ -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
View File
@@ -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> gb_internal 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> gb_internal 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> gb_internal 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> gb_internal Array<T> array_make (gbAllocator const &a);
template <typename T> Array<T> array_make (gbAllocator const &a, isize count); template <typename T> gb_internal 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> gb_internal 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> gb_internal Array<T> array_make_from_ptr (T *data, isize count, isize capacity);
template <typename T> void array_free (Array<T> *array); template <typename T> gb_internal void array_free (Array<T> *array);
template <typename T> void array_add (Array<T> *array, T const &t); template <typename T> gb_internal void array_add (Array<T> *array, T const &t);
template <typename T> T * array_add_and_get (Array<T> *array); template <typename T> gb_internal 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> gb_internal 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> gb_internal T array_pop (Array<T> *array);
template <typename T> void array_clear (Array<T> *array); template <typename T> gb_internal void array_clear (Array<T> *array);
template <typename T> void array_reserve (Array<T> *array, isize capacity); template <typename T> gb_internal void array_reserve (Array<T> *array, isize capacity);
template <typename T> void array_resize (Array<T> *array, isize count); template <typename T> gb_internal void array_resize (Array<T> *array, isize count);
template <typename T> void array_set_capacity (Array<T> *array, isize capacity); template <typename T> gb_internal 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> gb_internal 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 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> gb_internal 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_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> gb_internal 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, 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
View File
@@ -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); gb_internal void big_int_from_u64(BigInt *dst, u64 x);
void big_int_from_i64(BigInt *dst, i64 x); gb_internal void big_int_from_i64(BigInt *dst, i64 x);
void big_int_init (BigInt *dst, BigInt const *src); gb_internal 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_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); gb_internal BigInt big_int_make(BigInt const *b, bool abs=false);
BigInt big_int_make_abs(BigInt const *b); gb_internal BigInt big_int_make_abs(BigInt const *b);
BigInt big_int_make_u64(u64 x); gb_internal BigInt big_int_make_u64(u64 x);
BigInt big_int_make_i64(i64 x); gb_internal BigInt big_int_make_i64(i64 x);
u64 big_int_to_u64 (BigInt const *x); gb_internal u64 big_int_to_u64 (BigInt const *x);
i64 big_int_to_i64 (BigInt const *x); gb_internal i64 big_int_to_i64 (BigInt const *x);
f64 big_int_to_f64 (BigInt const *x); gb_internal f64 big_int_to_f64 (BigInt const *x);
String big_int_to_string(gbAllocator allocator, BigInt const *x, u64 base = 10); 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); gb_internal void big_int_add (BigInt *dst, BigInt const *x, BigInt const *y);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
void big_int_add_eq(BigInt *dst, BigInt const *x); gb_internal void big_int_add_eq(BigInt *dst, BigInt const *x);
void big_int_sub_eq(BigInt *dst, BigInt const *x); gb_internal void big_int_sub_eq(BigInt *dst, BigInt const *x);
void big_int_shl_eq(BigInt *dst, BigInt const *x); gb_internal void big_int_shl_eq(BigInt *dst, BigInt const *x);
void big_int_shr_eq(BigInt *dst, BigInt const *x); gb_internal 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_mul_eq(BigInt *dst, BigInt const *x);
void big_int_quo_eq(BigInt *dst, BigInt const *x); gb_internal 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_rem_eq(BigInt *dst, BigInt const *x);
bool big_int_is_neg(BigInt const *x); gb_internal bool big_int_is_neg(BigInt const *x);
void big_int_neg(BigInt *dst, 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
View File
@@ -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
View File
@@ -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) { gb_internal void add_library_collection(String name, String path) {
// TODO(bill): Check the path is valid and a directory
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}; gb_global String const WIN32_SEPARATOR_STRING = {cast(u8 *)"\\", 1};
String const NIX_SEPARATOR_STRING = {cast(u8 *)"/", 1}; gb_global String const NIX_SEPARATOR_STRING = {cast(u8 *)"/", 1};
String const WASM_MODULE_NAME_SEPARATOR = str_lit(".."); gb_global String const WASM_MODULE_NAME_SEPARATOR = str_lit("..");
String internal_odin_root_dir(void); gb_internal 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
View File
@@ -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) { gb_internal void check_or_else_expr_no_value_error(CheckerContext *c, String const &name, Operand const &x, Type *type_hint) {
// TODO(bill): better error message
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 (auto const &entry : c->info->packages) {
for_array(i, c->info->packages.entries) { AstPackage *pkg = entry.value;
AstPackage *pkg = c->info->packages.entries[i].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) { if (id != BuiltinProc_reverse_bits) {
// TODO(bill): Should this even be allowed at compile time?
} else {
u64 v = 0; u64 v = 0;
switch (id) { switch (id) {
case BuiltinProc_count_ones: case BuiltinProc_count_ones:
+27 -45
View File
@@ -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) { gb_internal Type *clone_enum_type(CheckerContext *ctx, Type *original_enum_type, Type *named_type) {
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) {
// 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) { MUTEX_GUARD_BLOCK(scope->mutex) for (auto const &entry : scope->elements) {
Entity *f = scope->elements.entries[i].value; 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) { for (auto const &entry : decl->deps) {
Entity *e = decl->deps.entries[i].ptr; 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) { for (auto const &entry : decl->type_info_deps) {
Type *t = decl->type_info_deps.entries[i].ptr; Type *t = entry.ptr;
ptr_set_add(&decl->parent->type_info_deps, t); ptr_set_add(&decl->parent->type_info_deps, t);
} }
+176 -203
View File
File diff suppressed because it is too large Load Diff
+33 -38
View File
@@ -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); gb_internal void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags);
void check_stmt(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) { MUTEX_GUARD_BLOCK(scope->mutex) for (auto const &entry : scope->elements) {
String name = scope->elements.entries[i].key.string; String name = entry.key.string;
Entity *decl = scope->elements.entries[i].value; 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) { for (auto const &entry : found->elements) {
Entity *f = found->elements.entries[i].value; 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) { for (auto const &entry : scope->elements) {
Entity *f = scope->elements.entries[i].value; 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
View File
@@ -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, 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) { 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, gb_internal Type *check_record_polymorphic_params(CheckerContext *ctx, Ast *polymorphic_params,
bool *is_polymorphic_, bool *is_polymorphic_,
Ast *node, Array<Operand> *poly_operands, Ast *node, Array<Operand> *poly_operands,
Type *named_type, Type *original_type_for_poly) { 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) { for (auto const &entry : scope->elements) {
Entity *e = scope->elements.entries[i].value; 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);
+337 -382
View File
File diff suppressed because it is too large Load Diff
+45 -48
View File
@@ -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 isize type_level;
CheckerPolyPath *poly_path;
isize poly_level; // TODO(bill): Actually handle correctly
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); gb_internal TypeAndValue type_and_value_of_expr (Ast *expr);
Type * type_of_expr (Ast *expr); gb_internal Type * type_of_expr (Ast *expr);
Entity * implicit_entity_of_node(Ast *clause); gb_internal Entity * implicit_entity_of_node(Ast *clause);
DeclInfo * decl_info_of_ident (Ast *ident); gb_internal DeclInfo * decl_info_of_ident (Ast *ident);
DeclInfo * decl_info_of_entity (Entity * e); gb_internal DeclInfo * decl_info_of_entity (Entity * e);
AstFile * ast_file_of_filename (CheckerInfo *i, String filename); 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); gb_internal Entity *entity_of_node(Ast *expr);
Entity *scope_lookup_current(Scope *s, String const &name); gb_internal Entity *scope_lookup_current(Scope *s, String const &name);
Entity *scope_lookup (Scope *s, String const &name); gb_internal Entity *scope_lookup (Scope *s, String const &name);
void scope_lookup_parent (Scope *s, String const &name, Scope **scope_, Entity **entity_); gb_internal 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 *scope_insert (Scope *s, Entity *entity, bool use_mutex=true);
void add_type_and_value (CheckerInfo *i, Ast *expression, AddressingMode mode, Type *type, ExactValue value); gb_internal void add_type_and_value (CheckerInfo *i, Ast *expression, AddressingMode mode, Type *type, ExactValue value);
ExprInfo *check_get_expr_info (CheckerContext *c, Ast *expr); gb_internal ExprInfo *check_get_expr_info (CheckerContext *c, Ast *expr);
void add_untyped (CheckerContext *c, Ast *expression, AddressingMode mode, Type *basic_type, ExactValue value); gb_internal void add_untyped (CheckerContext *c, Ast *expression, AddressingMode mode, Type *basic_type, ExactValue value);
void add_entity_use (CheckerContext *c, Ast *identifier, Entity *entity); gb_internal void add_entity_use (CheckerContext *c, Ast *identifier, Entity *entity);
void add_implicit_entity (CheckerContext *c, Ast *node, Entity *e); gb_internal 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); gb_internal 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 void add_type_info_type (CheckerContext *c, Type *t);
void check_add_import_decl(CheckerContext *c, Ast *decl); gb_internal void check_add_import_decl(CheckerContext *c, Ast *decl);
void check_add_foreign_import_decl(CheckerContext *c, Ast *decl); gb_internal void check_add_foreign_import_decl(CheckerContext *c, Ast *decl);
void check_entity_decl(CheckerContext *c, Entity *e, DeclInfo *d, Type *named_type); gb_internal 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); gb_internal 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_type_decl(CheckerContext *c, Entity *e, Ast *type_expr, Type *def);
bool check_arity_match(CheckerContext *c, AstValueDecl *vd, bool is_global = false); gb_internal bool check_arity_match(CheckerContext *c, AstValueDecl *vd, bool is_global = false);
void check_collect_entities(CheckerContext *c, Slice<Ast *> const &nodes); gb_internal void check_collect_entities(CheckerContext *c, Slice<Ast *> const &nodes);
void check_collect_entities_from_when_stmt(CheckerContext *c, AstWhenStmt *ws); gb_internal void check_collect_entities_from_when_stmt(CheckerContext *c, AstWhenStmt *ws);
void check_delayed_file_import_entity(CheckerContext *c, Ast *decl); gb_internal void check_delayed_file_import_entity(CheckerContext *c, Ast *decl);
CheckerTypePath *new_checker_type_path(); gb_internal CheckerTypePath *new_checker_type_path();
void destroy_checker_type_path(CheckerTypePath *tp); gb_internal void destroy_checker_type_path(CheckerTypePath *tp);
void check_type_path_push(CheckerContext *c, Entity *e); gb_internal void check_type_path_push(CheckerContext *c, Entity *e);
Entity *check_type_path_pop (CheckerContext *c); gb_internal Entity *check_type_path_pop (CheckerContext *c);
CheckerPolyPath *new_checker_poly_path(); gb_internal void init_core_context(Checker *c);
void destroy_checker_poly_path(CheckerPolyPath *); gb_internal void init_mem_allocator(Checker *c);
void check_poly_path_push(CheckerContext *c, Type *t); gb_internal void add_untyped_expressions(CheckerInfo *cinfo, UntypedExprInfoMap *untyped);
Type *check_poly_path_pop (CheckerContext *c);
void init_core_context(Checker *c);
void init_mem_allocator(Checker *c);
void add_untyped_expressions(CheckerInfo *cinfo, UntypedExprInfoMap *untyped);
+54 -45
View File
@@ -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); gb_internal i32 next_pow2(i32 n);
i64 next_pow2(i64 n); gb_internal i64 next_pow2(i64 n);
isize next_pow2_isize(isize n); gb_internal isize next_pow2_isize(isize n);
void debugf(char const *fmt, ...); 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
View File
@@ -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); gb_internal MemoryBlock *virtual_memory_alloc(isize size);
void virtual_memory_dealloc(MemoryBlock *block); gb_internal void virtual_memory_dealloc(MemoryBlock *block);
void *arena_alloc(Arena *arena, isize min_size, isize alignment); gb_internal void *arena_alloc(Arena *arena, isize min_size, isize alignment);
void arena_free_all(Arena *arena); 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); gb_internal PlatformMemoryBlock *platform_virtual_memory_alloc(isize total_size);
void platform_virtual_memory_free(PlatformMemoryBlock *block); gb_internal void platform_virtual_memory_free(PlatformMemoryBlock *block);
void platform_virtual_memory_protect(void *memory, isize size); 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) { gb_internal void platform_virtual_memory_free(PlatformMemoryBlock *block) {
global_platform_memory_total_usage -= block->total_size; 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
View File
@@ -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, ...) { gb_internal void print_doc_line_no_newline(i32 indent, String const &data) {
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) {
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);
} }
gb_internal void print_doc_package(CheckerInfo *info, AstPackage *pkg) {
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) { for (auto const &entry : pkg->scope->elements) {
Entity *e = pkg->scope->elements.entries[i].value; 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) { for (auto const &entry : info->packages) {
AstPackage *pkg = info->packages.entries[i].value; 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
View File
@@ -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
View File
@@ -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); gb_internal OdinDocEntityIndex odin_doc_add_entity(OdinDocWriter *w, Entity *e);
OdinDocTypeIndex odin_doc_type(OdinDocWriter *w, Type *type); 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) { for (auto const &entry : w->entity_cache) {
Entity *e = w->entity_cache.entries[i].key; array_add(&entities, entry.key);
entities[i] = e;
} }
for_array(i, entities) { for (Entity *e : entities) {
Entity *e = entities[i];
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) { for (auto const &entry : w->entity_cache) {
Entity *e = w->entity_cache.entries[i].key; Entity *e = entry.key;
OdinDocEntityIndex entity_index = w->entity_cache.entries[i].value; 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) { for (Entity *entity : e->ProcGroup.entities) {
OdinDocEntityIndex index = odin_doc_add_entity(w, e->ProcGroup.entities[j]); 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) { for (auto const &element : pkg->scope->elements) {
String name = pkg->scope->elements.entries[i].key.string; String name = element.key.string;
Entity *e = pkg->scope->elements.entries[i].value; 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) { for (auto const &entry : w->info->packages) {
AstPackage *pkg = w->info->packages.entries[i].value; 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
View File
@@ -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;
} }
gb_internal Entity *alloc_entity_import_name(Scope *scope, Token token, Type *type,
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,
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
View File
@@ -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); gb_internal bool global_warnings_as_errors(void);
bool global_ignore_warnings(void); gb_internal bool global_ignore_warnings(void);
bool show_error_line(void); gb_internal bool show_error_line(void);
gbString get_file_line_as_string(TokenPos const &pos, i32 *offset); 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);
+81 -91
View File
@@ -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) { // gb_internal ExactValue exact_value_make_imag(ExactValue v) {
switch (v.kind) { // switch (v.kind) {
case ExactValue_Integer: // case ExactValue_Integer:
return exact_value_complex(0, exact_value_to_float(v).value_float); // return exact_value_complex(0, exact_value_to_float(v).value_float);
case ExactValue_Float: // case ExactValue_Float:
return exact_value_complex(0, v.value_float); // return exact_value_complex(0, v.value_float);
default: // default:
GB_PANIC("Expected an integer or float type for 'exact_value_make_imag'"); // GB_PANIC("Expected an integer or float type for 'exact_value_make_imag'");
} // }
ExactValue r = {ExactValue_Invalid}; // ExactValue r = {ExactValue_Invalid};
return r; // return r;
} // }
ExactValue exact_value_make_jmag(ExactValue v) { // gb_internal ExactValue exact_value_make_jmag(ExactValue v) {
switch (v.kind) { // switch (v.kind) {
case ExactValue_Integer: // case ExactValue_Integer:
return exact_value_quaternion(0, 0, exact_value_to_float(v).value_float, 0); // return exact_value_quaternion(0, 0, exact_value_to_float(v).value_float, 0);
case ExactValue_Float: // case ExactValue_Float:
return exact_value_quaternion(0, 0, v.value_float, 0); // return exact_value_quaternion(0, 0, v.value_float, 0);
default: // default:
GB_PANIC("Expected an integer or float type for 'exact_value_make_imag'"); // GB_PANIC("Expected an integer or float type for 'exact_value_make_jmag'");
} // }
ExactValue r = {ExactValue_Invalid}; // ExactValue r = {ExactValue_Invalid};
return r; // return r;
} // }
ExactValue exact_value_make_kmag(ExactValue v) { // gb_internal ExactValue exact_value_make_kmag(ExactValue v) {
switch (v.kind) { // switch (v.kind) {
case ExactValue_Integer: // case ExactValue_Integer:
return exact_value_quaternion(0, 0, 0, exact_value_to_float(v).value_float); // return exact_value_quaternion(0, 0, 0, exact_value_to_float(v).value_float);
case ExactValue_Float: // case ExactValue_Float:
return exact_value_quaternion(0, 0, 0, v.value_float); // return exact_value_quaternion(0, 0, 0, v.value_float);
default: // default:
GB_PANIC("Expected an integer or float type for 'exact_value_make_imag'"); // GB_PANIC("Expected an integer or float type for 'exact_value_make_kmag'");
} // }
ExactValue r = {ExactValue_Invalid}; // ExactValue r = {ExactValue_Invalid};
return r; // return r;
} // }
i64 exact_value_to_i64(ExactValue v) { 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); gb_internal Entity *strip_entity_wrapping(Ast *expr);
Entity *strip_entity_wrapping(Entity *e); 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
View File
@@ -18,21 +18,21 @@ struct lbArgType {
}; };
i64 lb_sizeof(LLVMTypeRef type); gb_internal i64 lb_sizeof(LLVMTypeRef type);
i64 lb_alignof(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); gb_internal Array<lbArgType> compute_arg_types(LLVMContextRef c, LLVMTypeRef *arg_types, unsigned arg_count);
LB_ABI_COMPUTE_RETURN_TYPE(compute_return_type); 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); gb_internal Array<lbArgType> compute_arg_types(LLVMContextRef c, LLVMTypeRef *arg_types, unsigned arg_count);
LB_ABI_COMPUTE_RETURN_TYPE(compute_return_type); 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); gb_internal LB_ABI_COMPUTE_RETURN_TYPE(compute_return_type);
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);
void fixup(LLVMTypeRef t, Array<RegClass> *cls); gb_internal void fixup(LLVMTypeRef t, Array<RegClass> *cls);
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);
Array<RegClass> classify(LLVMTypeRef t); gb_internal Array<RegClass> classify(LLVMTypeRef t);
LLVMTypeRef llreg(LLVMContextRef c, Array<RegClass> const &reg_classes); 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); gb_internal Array<lbArgType> compute_arg_types(LLVMContextRef c, LLVMTypeRef *arg_types, unsigned arg_count);
LB_ABI_COMPUTE_RETURN_TYPE(compute_return_type); gb_internal LB_ABI_COMPUTE_RETURN_TYPE(compute_return_type);
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_);
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); gb_internal Array<lbArgType> compute_arg_types(LLVMContextRef c, LLVMTypeRef *arg_types, unsigned arg_count);
LB_ABI_COMPUTE_RETURN_TYPE(compute_return_type); 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); gb_internal 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 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
View File
@@ -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) { // gb_internal void lb_debug_print(lbProcedure *p, String const &str) {
auto args = array_make<lbValue>(heap_allocator(), 1); // auto args = array_make<lbValue>(heap_allocator(), 1);
args[0] = lb_const_string(p->module, str); // args[0] = lb_const_string(p->module, str);
lb_emit_runtime_call(p, "print_string", args); // 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, 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) { 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) { for (auto const &entry : m->objc_classes) {
auto const &entry = m->objc_classes.entries[i];
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) { for (auto const &entry : m->objc_selectors) {
auto const &entry = m->objc_selectors.entries[i];
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) { for (auto &var : global_variables) {
auto *var = &global_variables[i]; if (var.is_initialized) {
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, LLVMGetUndef(global_type));
LLVMSetInitializer(var->var.value, LLVMConstNull(global_type)); LLVMSetInitializer(var.var.value, LLVMConstNull(global_type));
var->is_initialized = true; 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)); LLVMSetInitializer(var.var.value, LLVMConstNull(global_type));
var->is_initialized = true; 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); LLVMSetInitializer(var.var.value, init.value);
var->is_initialized = true; var.is_initialized = true;
continue; continue;
} }
} else { } else {
var->init = init; var.init = init;
} }
} }
if (var->init.value != nullptr) { if (var.init.value != nullptr) {
GB_ASSERT(!var->is_initialized); GB_ASSERT(!var.is_initialized);
Type *t = type_deref(var->var.type); 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); Type *var_type = default_type(var.init.type);
lbAddr g = lb_add_global_generated(main_module, var_type, var->init); lbAddr g = lb_add_global_generated(main_module, var_type, var.init);
lb_addr_store(p, g, 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 data = lb_emit_struct_ep(p, var.var, 0);
lbValue ti = lb_emit_struct_ep(p, var->var, 1); 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); LLVMTypeRef vt = llvm_addr_type(p->module, var.var);
lbValue src0 = lb_emit_conv(p, var->init, t); 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) { isize testing_proc_index = 0;
Entity *testing_proc = m->info->testing_procedures[i]; 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 (lbProcedure *p : m->procedures_to_generate) {
for_array(i, m->procedures_to_generate) {
lbProcedure *p = m->procedures_to_generate[i];
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) { for (auto const &entry : m->equal_procs) {
lbProcedure *p = m->equal_procs.entries[i].value; 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) { for (auto const &entry : m->hasher_procs) {
lbProcedure *p = m->hasher_procs.entries[i].value; 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) { for (auto const &entry : m->map_get_procs) {
lbProcedure *p = m->map_get_procs.entries[i].value; 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) { for (auto const &entry : m->map_set_procs) {
lbProcedure *p = m->map_set_procs.entries[i].value; 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) { for (auto const &entry : gen->modules) {
LLVMSetTarget(gen->modules.entries[i].value->mod, target_triple); 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) { for (auto const &entry : gen->modules) {
target_machines[i] = LLVMCreateTargetMachine( 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) { for (auto const &entry : gen->modules) {
lbModule *m = gen->modules.entries[i].value; lbModule *m = entry.value;
if (m->debug_builder) { // Debug Info if (m->debug_builder) { // Debug Info
for_array(i, info->files.entries) { for (auto const &file_entry : info->files) {
AstFile *f = info->files.entries[i].value; AstFile *f = file_entry.value;
String fullpath = f->fullpath;
String filename = remove_directory_from_path(fullpath);
String directory = directory_from_path(fullpath);
LLVMMetadataRef res = LLVMDIBuilderCreateFile(m->debug_builder, LLVMMetadataRef res = LLVMDIBuilderCreateFile(m->debug_builder,
cast(char const *)filename.text, filename.len, cast(char const *)f->filename.text, f->filename.len,
cast(char const *)directory.text, directory.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) { for (Type *t : m->info->type_info_types) {
Type *t = m->info->type_info_types[entry_index];
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) { for (Entity *e : info->entities) {
Entity *e = info->entities[i];
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) { for (DeclInfo *d : info->variable_init_order) {
DeclInfo *d = info->variable_init_order[i];
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) { for (auto const &entry : builtin_pkg->scope->elements) {
Entity *e = builtin_pkg->scope->elements.entries[i].value; 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) { for (Entity *e : info->entities) {
Entity *e = info->entities[i];
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) { for (auto const &entry : gen->modules) {
lbModule *m = gen->modules.entries[j].value; lbModule *m = entry.value;
for_array(i, m->procedures_to_generate) { // 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) { for (auto const &entry : gen->modules) {
lbModule *m = gen->modules.entries[j].value; lbModule *m = entry.value;
for_array(i, m->missing_procedures_to_check) { // 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) { for (auto const &entry : gen->modules) {
lbModule *m = gen->modules.entries[j].value; 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) { for (auto const &entry : gen->modules) {
lbModule *m = gen->modules.entries[i].value; 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) { for (auto const &entry : gen->modules) {
lbModule *m = gen->modules.entries[i].value; 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) { for (auto const &entry : gen->modules) {
lbModule *m = gen->modules.entries[j].value; 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) { for (auto const &entry : gen->modules) {
lbModule *m = gen->modules.entries[j].value; 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) { for (auto const &entry : gen->modules) {
lbModule *m = gen->modules.entries[j].value; 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) { for (auto const &entry : gen->modules) {
lbModule *m = gen->modules.entries[j].value; 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) { for (auto const &entry : gen->modules) {
lbModule *m = gen->modules.entries[j].value; 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) { for (auto const &entry : gen->modules) {
lbModule *m = gen->modules.entries[j].value; 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
View File
@@ -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); gb_internal String lb_mangle_name(lbModule *m, Entity *e);
String lb_get_entity_name(lbModule *m, Entity *e, String name = {}); 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); gb_internal 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); gb_internal 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); gb_internal 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); gb_internal 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); gb_internal lbProcedure *lb_create_procedure(lbModule *module, Entity *entity, bool ignore_body=false);
void lb_end_procedure(lbProcedure *p); gb_internal void lb_end_procedure(lbProcedure *p);
LLVMTypeRef lb_type(lbModule *m, Type *type); gb_internal LLVMTypeRef lb_type(lbModule *m, Type *type);
LLVMTypeRef llvm_get_element_type(LLVMTypeRef 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); gb_internal lbValue lb_const_nil(lbModule *m, Type *type);
lbValue lb_const_undef(lbModule *m, Type *type); gb_internal lbValue lb_const_undef(lbModule *m, Type *type);
lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_local=true); gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_local=true);
lbValue lb_const_bool(lbModule *m, Type *type, bool value); gb_internal 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_int(lbModule *m, Type *type, u64 value);
lbAddr lb_addr(lbValue addr); gb_internal lbAddr lb_addr(lbValue addr);
Type *lb_addr_type(lbAddr const &addr); gb_internal Type *lb_addr_type(lbAddr const &addr);
LLVMTypeRef llvm_addr_type(lbModule *module, lbValue addr_val); gb_internal LLVMTypeRef llvm_addr_type(lbModule *module, lbValue addr_val);
void lb_addr_store(lbProcedure *p, lbAddr addr, lbValue value); gb_internal void lb_addr_store(lbProcedure *p, lbAddr addr, lbValue value);
lbValue lb_addr_load(lbProcedure *p, lbAddr const &addr); gb_internal lbValue lb_addr_load(lbProcedure *p, lbAddr const &addr);
lbValue lb_emit_load(lbProcedure *p, lbValue v); gb_internal lbValue lb_emit_load(lbProcedure *p, lbValue v);
void lb_emit_store(lbProcedure *p, lbValue ptr, lbValue value); gb_internal void lb_emit_store(lbProcedure *p, lbValue ptr, lbValue value);
void lb_build_stmt(lbProcedure *p, Ast *stmt); gb_internal void lb_build_stmt(lbProcedure *p, Ast *stmt);
lbValue lb_build_expr(lbProcedure *p, Ast *expr); gb_internal lbValue lb_build_expr(lbProcedure *p, Ast *expr);
lbAddr lb_build_addr(lbProcedure *p, Ast *expr); gb_internal 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_list(lbProcedure *p, Array<Ast *> const &stmts);
lbValue lb_emit_epi(lbProcedure *p, lbValue const &value, isize index); gb_internal lbValue lb_emit_epi(lbProcedure *p, lbValue const &value, isize 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);
lbValue lb_emit_array_epi(lbModule *m, lbValue s, isize index); gb_internal lbValue lb_emit_array_epi(lbModule *m, lbValue s, isize 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);
lbValue lb_emit_struct_ev(lbProcedure *p, lbValue s, i32 index); gb_internal lbValue lb_emit_struct_ev(lbProcedure *p, lbValue s, i32 index);
lbValue lb_emit_tuple_ev(lbProcedure *p, lbValue value, i32 index); gb_internal lbValue lb_emit_tuple_ev(lbProcedure *p, lbValue value, i32 index);
lbValue lb_emit_array_epi(lbProcedure *p, lbValue value, isize index); gb_internal lbValue lb_emit_array_epi(lbProcedure *p, lbValue value, isize index);
lbValue lb_emit_array_ep(lbProcedure *p, lbValue s, lbValue index); gb_internal lbValue lb_emit_array_ep(lbProcedure *p, lbValue s, lbValue index);
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);
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 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);
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);
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);
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);
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);
void lb_emit_defer_stmts(lbProcedure *p, lbDeferExitKind kind, lbBlock *block); gb_internal void lb_emit_defer_stmts(lbProcedure *p, lbDeferExitKind kind, lbBlock *block);
lbValue lb_emit_transmute(lbProcedure *p, lbValue value, Type *t); gb_internal lbValue lb_emit_transmute(lbProcedure *p, lbValue value, Type *t);
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);
lbValue lb_emit_call(lbProcedure *p, lbValue value, Array<lbValue> const &args, ProcInlining inlining = ProcInlining_none); gb_internal 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); gb_internal 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_comp_against_nil(lbProcedure *p, TokenKind op_kind, lbValue x);
void lb_emit_jump(lbProcedure *p, lbBlock *target_block); gb_internal void lb_emit_jump(lbProcedure *p, lbBlock *target_block);
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);
void lb_start_block(lbProcedure *p, lbBlock *b); 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); gb_internal lbAddr lb_find_or_generate_context_ptr(lbProcedure *p);
lbContextData *lb_push_context_onto_stack(lbProcedure *p, lbAddr ctx); gb_internal lbContextData *lb_push_context_onto_stack(lbProcedure *p, lbAddr ctx);
lbContextData *lb_push_context_onto_stack_from_implicit_parameter(lbProcedure *p); 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); gb_internal 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_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); gb_internal lbValue lb_address_from_load_or_generate_local(lbProcedure *p, lbValue value);
lbValue lb_address_from_load(lbProcedure *p, lbValue value); gb_internal lbValue lb_address_from_load(lbProcedure *p, lbValue value);
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);
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);
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); gb_internal lbValue lb_emit_ptr_offset(lbProcedure *p, lbValue ptr, lbValue index);
lbValue lb_string_elem(lbProcedure *p, lbValue string); gb_internal lbValue lb_string_elem(lbProcedure *p, lbValue string);
lbValue lb_string_len(lbProcedure *p, lbValue string); gb_internal lbValue lb_string_len(lbProcedure *p, lbValue string);
lbValue lb_cstring_len(lbProcedure *p, lbValue value); gb_internal 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);
lbValue lb_slice_elem(lbProcedure *p, lbValue slice); gb_internal lbValue lb_slice_elem(lbProcedure *p, lbValue slice);
lbValue lb_slice_len(lbProcedure *p, lbValue slice); gb_internal lbValue lb_slice_len(lbProcedure *p, lbValue slice);
lbValue lb_dynamic_array_elem(lbProcedure *p, lbValue da); gb_internal lbValue lb_dynamic_array_elem(lbProcedure *p, lbValue da);
lbValue lb_dynamic_array_len(lbProcedure *p, lbValue da); gb_internal lbValue lb_dynamic_array_len(lbProcedure *p, lbValue da);
lbValue lb_dynamic_array_cap(lbProcedure *p, lbValue da); gb_internal lbValue lb_dynamic_array_cap(lbProcedure *p, lbValue da);
lbValue lb_dynamic_array_allocator(lbProcedure *p, lbValue da); gb_internal lbValue lb_dynamic_array_allocator(lbProcedure *p, lbValue da);
lbValue lb_map_len(lbProcedure *p, lbValue value); gb_internal lbValue lb_map_len(lbProcedure *p, lbValue value);
lbValue lb_map_cap(lbProcedure *p, lbValue value); gb_internal lbValue lb_map_cap(lbProcedure *p, lbValue value);
lbValue lb_soa_struct_len(lbProcedure *p, lbValue value); gb_internal lbValue lb_soa_struct_len(lbProcedure *p, lbValue value);
void lb_emit_increment(lbProcedure *p, lbValue addr); gb_internal 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_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); gb_internal 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_generate_anonymous_proc_lit(lbModule *m, String const &prefix_name, Ast *expr, lbProcedure *parent = nullptr);
bool lb_is_const(lbValue value); gb_internal bool lb_is_const(lbValue value);
bool lb_is_const_or_global(lbValue value); gb_internal bool lb_is_const_or_global(lbValue value);
bool lb_is_const_nil(lbValue value); gb_internal bool lb_is_const_nil(lbValue value);
String lb_get_const_string(lbModule *m, 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); gb_internal 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); gb_internal 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_); gb_internal 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); gb_internal 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_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); gb_internal 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); 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);
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);
lbValue lb_find_procedure_value_from_entity(lbModule *m, Entity *e); gb_internal 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_value_from_entity(lbModule *m, Entity *e);
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);
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);
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);
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); gb_internal lbValue lb_equal_proc_for_type(lbModule *m, Type *type);
lbValue lb_hasher_proc_for_type(lbModule *m, Type *type); gb_internal lbValue lb_hasher_proc_for_type(lbModule *m, Type *type);
lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t); 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); gb_internal lbValue lb_emit_count_ones(lbProcedure *p, lbValue x, Type *type);
lbValue lb_emit_count_zeros(lbProcedure *p, lbValue x, Type *type); gb_internal 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);
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);
lbValue lb_emit_reverse_bits(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); gb_internal 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); gb_internal 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 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_); gb_internal 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_); gb_internal 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 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); gb_internal lbValue lb_expr_untyped_const_to_typed(lbModule *m, Ast *expr, Type *t);
bool lb_is_expr_untyped_const(Ast *expr); 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); gb_internal lbStructFieldRemapping lb_get_struct_remapping(lbModule *m, Type *t);
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);
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); gb_internal 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); gb_internal 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); gb_internal 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_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); gb_internal LLVMTypeRef OdinLLVMGetArrayElementType(LLVMTypeRef type);
LLVMTypeRef OdinLLVMGetVectorElementType(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
View File
@@ -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
View File
@@ -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
View File
@@ -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); gb_internal lbValue lb_build_expr_internal(lbProcedure *p, Ast *expr);
lbValue lb_build_expr(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); gb_internal lbAddr lb_build_addr_internal(lbProcedure *p, Ast *expr);
lbAddr lb_build_addr(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
View File
@@ -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) { for (auto const &entry : gen->info->packages) {
AstPackage *pkg = gen->info->packages.entries[i].value; 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) { for (auto const &entry : gen->modules) {
lbModule *m = gen->modules.entries[i].value; 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_internal bool lb_is_type_proc_recursive(Type *t) {
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) {
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) { gb_internal String lb_mangle_name(lbModule *m, Entity *e) {
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) {
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) { gb_internal void lb_add_procedure_value(lbModule *m, lbProcedure *p) {
string_map_set(&m->members, key, val);
}
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) { gb_internal lbValue lb_find_or_add_entity_string_byte_slice_with_type(lbModule *m, String const &str, Type *slice_type) {
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_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) {
+25 -25
View File
@@ -32,21 +32,21 @@
**************************************************************************/ **************************************************************************/
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);
void lb_add_function_simplifcation_passes(LLVMPassManagerRef mpm, i32 optimization_level); gb_internal 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); gb_internal 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); gb_internal 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) { // gb_internal LLVMBool lb_must_preserve_predicate_callback(LLVMValueRef value, void *user_data) {
lbModule *m = cast(lbModule *)user_data; // lbModule *m = cast(lbModule *)user_data;
if (m == nullptr) { // if (m == nullptr) {
return false; // return false;
} // }
if (value == nullptr) { // if (value == nullptr) {
return false; // return false;
} // }
return LLVMIsAAllocaInst(value) != nullptr; // 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;
+63 -72
View File
@@ -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_) { // gb_internal lbValue lb_value_param(lbProcedure *p, Entity *e, Type *abi_type, i32 index, lbParamPasskind *kind_) {
lbParamPasskind kind = lbParamPass_Value; // lbParamPasskind kind = lbParamPass_Value;
if (e != nullptr && !are_types_identical(abi_type, e->type)) { // if (e != nullptr && !are_types_identical(abi_type, e->type)) {
if (is_type_pointer(abi_type)) { // if (is_type_pointer(abi_type)) {
GB_ASSERT(e->kind == Entity_Variable); // GB_ASSERT(e->kind == Entity_Variable);
Type *av = core_type(type_deref(abi_type)); // Type *av = core_type(type_deref(abi_type));
if (are_types_identical(av, core_type(e->type))) { // if (are_types_identical(av, core_type(e->type))) {
kind = lbParamPass_Pointer; // kind = lbParamPass_Pointer;
if (e->flags&EntityFlag_Value) { // if (e->flags&EntityFlag_Value) {
kind = lbParamPass_ConstRef; // kind = lbParamPass_ConstRef;
} // }
} else { // } else {
kind = lbParamPass_BitCast; // kind = lbParamPass_BitCast;
} // }
} else if (is_type_integer(abi_type)) { // } else if (is_type_integer(abi_type)) {
kind = lbParamPass_Integer; // kind = lbParamPass_Integer;
} else if (abi_type == t_llvm_bool) { // } else if (abi_type == t_llvm_bool) {
kind = lbParamPass_Value; // kind = lbParamPass_Value;
} else if (is_type_boolean(abi_type)) { // } else if (is_type_boolean(abi_type)) {
kind = lbParamPass_Integer; // kind = lbParamPass_Integer;
} else if (is_type_simd_vector(abi_type)) { // } else if (is_type_simd_vector(abi_type)) {
kind = lbParamPass_BitCast; // kind = lbParamPass_BitCast;
} else if (is_type_float(abi_type)) { // } else if (is_type_float(abi_type)) {
kind = lbParamPass_BitCast; // kind = lbParamPass_BitCast;
} else if (is_type_tuple(abi_type)) { // } else if (is_type_tuple(abi_type)) {
kind = lbParamPass_Tuple; // kind = lbParamPass_Tuple;
} else if (is_type_proc(abi_type)) { // } else if (is_type_proc(abi_type)) {
kind = lbParamPass_Value; // kind = lbParamPass_Value;
} else { // } else {
GB_PANIC("Invalid abi type pass kind %s", type_to_string(abi_type)); // GB_PANIC("Invalid abi type pass kind %s", type_to_string(abi_type));
} // }
} // }
if (kind_) *kind_ = kind; // if (kind_) *kind_ = kind;
lbValue res = {}; // lbValue res = {};
res.value = LLVMGetParam(p->value, cast(unsigned)index); // res.value = LLVMGetParam(p->value, cast(unsigned)index);
res.type = abi_type; // res.type = abi_type;
return res; // return res;
} // }
void lb_start_block(lbProcedure *p, lbBlock *b) { 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) { gb_internal LLVMValueRef llvm_splat_int(i64 count, LLVMTypeRef type, i64 value, bool is_signed=false) {
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) {
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
View File
@@ -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, 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_) { 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_) { gb_internal lbValue lb_map_hash_is_valid(lbProcedure *p, lbValue hash) {
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) {
// 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, gb_internal void lb_build_range_map(lbProcedure *p, lbValue expr, Type *val_type,
lbValue *val_, lbValue *key_, lbBlock **loop_, lbBlock **done_) { 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, gb_internal void lb_build_range_string(lbProcedure *p, lbValue expr, Type *val_type,
lbValue *val_, lbValue *idx_, lbBlock **loop_, lbBlock **done_) { 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, gb_internal void lb_build_range_interval(lbProcedure *p, AstBinaryExpr *node,
AstRangeStmt *rs, Scope *scope) { 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, 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_) { 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
View File
@@ -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
View File
@@ -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); gb_internal 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_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_internal lbValue lb_emit_union_cast_only_ok_check(lbProcedure *p, lbValue value, Type *type, TokenPos pos) {
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_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
View File
@@ -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) { if (build_context.show_timings) {
generate_and_print_query_data(checker, &global_timings); show_timings(checker, &global_timings);
} else {
if (build_context.show_timings) {
show_timings(checker, &global_timings);
}
} }
if (global_error_collector.count != 0) { if (global_error_collector.count != 0) {
+20 -20
View File
@@ -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);
+266 -305
View File
File diff suppressed because it is too large Load Diff
+53 -47
View File
@@ -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 // This is effectively a queue but does not require any multi-threading capabilities
// any multiple thread capabilities Array<Ast *> delayed_decls_queues[AstDelayQueue_COUNT];
MPMCQueue<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; String init_fullpath;
StringSet imported_files; // fullpath
Array<AstPackage *> packages; StringSet imported_files; // fullpath
Array<ImportedPackage> package_imports; BlockingMutex imported_files_mutex;
isize file_to_process_count;
isize total_token_count; Array<AstPackage *> packages;
isize total_line_count; BlockingMutex packages_mutex;
BlockingMutex wait_mutex;
BlockingMutex import_mutex; std::atomic<isize> file_to_process_count;
BlockingMutex file_add_mutex; std::atomic<isize> total_token_count;
BlockingMutex file_decl_mutex; std::atomic<isize> total_line_count;
BlockingMutex packages_mutex;
MPMCQueue<ParseFileError> file_error_queue; // 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); gb_internal gbString expr_to_string(Ast *expression);
bool allow_field_separator(AstFile *f); gb_internal bool allow_field_separator(AstFile *f);
+2 -4
View File
@@ -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
View File
@@ -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
View File
@@ -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 = {};
+58 -37
View File
@@ -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> gb_internal 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> gb_internal 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> gb_internal 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> gb_internal 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> gb_internal 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> gb_internal void map_clear (PtrMap<K, V> *h);
template <typename K, typename V> void map_grow (PtrMap<K, V> *h); template <typename K, typename V> gb_internal 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> gb_internal 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_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> gb_internal 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> gb_internal 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> gb_internal 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> gb_internal 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> gb_internal 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> gb_internal 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 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
View File
@@ -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> gb_internal 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> gb_internal void ptr_set_destroy(PtrSet<T> *s);
template <typename T> T ptr_set_add (PtrSet<T> *s, T ptr); template <typename T> gb_internal 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> gb_internal 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> gb_internal bool ptr_set_exists (PtrSet<T> *s, T ptr);
template <typename T> void ptr_set_remove (PtrSet<T> *s, T ptr); template <typename T> gb_internal void ptr_set_remove (PtrSet<T> *s, T ptr);
template <typename T> void ptr_set_clear (PtrSet<T> *s); template <typename T> gb_internal void ptr_set_clear (PtrSet<T> *s);
template <typename T> void ptr_set_grow (PtrSet<T> *s); template <typename T> gb_internal void ptr_set_grow (PtrSet<T> *s);
template <typename T> void ptr_set_rehash (PtrSet<T> *s, isize new_count); template <typename T> gb_internal 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_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;
}
-1030
View File
File diff suppressed because it is too large Load Diff
+6 -6
View File
@@ -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
View File
@@ -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) { // gb_internal bool range_cache_index_exists(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) {
return true; // return true;
} // }
} // }
return false; // return false;
} // }
+57 -71
View File
@@ -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_internal gb_inline bool str_eq_ignore_case(String const &a, String const &b) {
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) { gb_internal gb_inline bool str_eq(String const &a, String const &b) {
String x = *(String *)a;
String y = *(String *)b;
return string_compare(x, y);
}
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_internal 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_internal 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_internal 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_internal 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_internal 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_internal 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_internal 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_internal 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_internal 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_internal 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); } gb_internal 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> 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> 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_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> 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> 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_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> 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> bool operator >= (String const &a, char const (&b)[N]) { return str_ge(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_inline bool string_starts_with(String const &s, String const &prefix) { 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
View File
@@ -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> gb_internal 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_destroy (StringMap<T> *h);
template <typename T> T * string_map_get (StringMap<T> *h, char const *key); template <typename T> gb_internal 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> gb_internal 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, StringHashKey const &key);
template <typename T> T & string_map_must_get (StringMap<T> *h, char const *key); template <typename T> gb_internal 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> gb_internal 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, StringHashKey const &key);
template <typename T> 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, 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> gb_internal 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, char const *key, T const &value);
template <typename T> void string_map_remove (StringMap<T> *h, StringHashKey const &key); template <typename T> gb_internal void string_map_remove (StringMap<T> *h, StringHashKey const &key);
template <typename T> void string_map_clear (StringMap<T> *h); template <typename T> gb_internal void string_map_clear (StringMap<T> *h);
template <typename T> void string_map_grow (StringMap<T> *h); template <typename T> gb_internal void string_map_grow (StringMap<T> *h);
template <typename T> void string_map_rehash (StringMap<T> *h, isize new_count); template <typename T> gb_internal 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_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;
}
+38 -20
View File
@@ -10,18 +10,18 @@ struct StringSet {
}; };
void string_set_init (StringSet *s, gbAllocator a, isize capacity = 16); gb_internal void string_set_init (StringSet *s, gbAllocator a, isize capacity = 16);
void string_set_destroy(StringSet *s); gb_internal void string_set_destroy(StringSet *s);
void string_set_add (StringSet *s, String const &str); gb_internal void string_set_add (StringSet *s, String const &str);
bool string_set_update (StringSet *s, String const &str); // returns true if it previously existed gb_internal bool string_set_update (StringSet *s, String const &str); // returns true if it previously existed
bool string_set_exists (StringSet *s, String const &str); gb_internal bool string_set_exists (StringSet *s, String const &str);
void string_set_remove (StringSet *s, String const &str); gb_internal void string_set_remove (StringSet *s, String const &str);
void string_set_clear (StringSet *s); gb_internal void string_set_clear (StringSet *s);
void string_set_grow (StringSet *s); gb_internal void string_set_grow (StringSet *s);
void string_set_rehash (StringSet *s, isize new_count); gb_internal void string_set_rehash (StringSet *s, isize new_count);
gb_inline void string_set_init(StringSet *s, gbAllocator a, isize capacity) { 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
View File
@@ -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); thread_init_and_start(t, thread_pool_thread_proc, pool);
}
for_array(i, pool->threads) {
Thread *t = &pool->threads[i];
thread_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
View File
@@ -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); 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);
bool mutex_try_lock(BlockingMutex *m); gb_internal bool mutex_try_lock(BlockingMutex *m);
void mutex_unlock (BlockingMutex *m); gb_internal void mutex_unlock (BlockingMutex *m);
void mutex_init (RecursiveMutex *m); gb_internal void mutex_init (RecursiveMutex *m);
void mutex_destroy (RecursiveMutex *m); gb_internal void mutex_destroy (RecursiveMutex *m);
void mutex_lock (RecursiveMutex *m); gb_internal void mutex_lock (RecursiveMutex *m);
bool mutex_try_lock(RecursiveMutex *m); gb_internal bool mutex_try_lock(RecursiveMutex *m);
void mutex_unlock (RecursiveMutex *m); gb_internal void mutex_unlock (RecursiveMutex *m);
void semaphore_init (Semaphore *s); gb_internal void semaphore_init (Semaphore *s);
void semaphore_destroy(Semaphore *s); gb_internal void semaphore_destroy(Semaphore *s);
void semaphore_post (Semaphore *s, i32 count); gb_internal void semaphore_post (Semaphore *s, i32 count);
void semaphore_wait (Semaphore *s); gb_internal void semaphore_wait (Semaphore *s);
void semaphore_release(Semaphore *s) { semaphore_post(s, 1); } gb_internal void semaphore_release(Semaphore *s) { semaphore_post(s, 1); }
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);
void condition_signal(Condition *c); gb_internal void condition_signal(Condition *c);
void condition_wait(Condition *c, BlockingMutex *m); gb_internal void condition_wait(Condition *c, BlockingMutex *m);
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);
u32 thread_current_id(void); gb_internal u32 thread_current_id(void);
void thread_init (Thread *t); gb_internal void thread_init_and_start (Thread *t, ThreadProc *proc, void *data);
void thread_destroy (Thread *t); gb_internal void thread_init_and_start_with_stack(Thread *t, ThreadProc *proc, void *data, isize stack_size);
void thread_start (Thread *t, ThreadProc *proc, void *data); gb_internal void thread_join_and_destroy(Thread *t);
void thread_start_with_stack(Thread *t, ThreadProc *proc, void *data, isize stack_size); gb_internal bool thread_is_running (Thread const *t);
void thread_join (Thread *t); gb_internal void thread_set_name (Thread *t, char const *name);
bool thread_is_running (Thread const *t);
void thread_set_name (Thread *t, char const *name);
void yield_thread(void); gb_internal void yield_thread(void);
void yield_process(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); } gb_internal 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); } gb_internal 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); } gb_internal 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_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); } gb_internal void semaphore_init (Semaphore *s) { sem_init(&s->unix_handle, 0, 0); }
void semaphore_destroy(Semaphore *s) { sem_destroy(&s->unix_handle); } gb_internal 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_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;
}
gb_internal u32 thread_current_id(void) {
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
} }
gb_internal void private__thread_run(Thread *t) {
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);
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
View File
@@ -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
View File
@@ -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); gb_internal String get_file_path_string(i32 index);
struct AstFile *thread_safe_get_ast_file_from_id(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; } gb_internal gb_inline 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; }
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; }
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; }
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; }
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;
+311 -430
View File
File diff suppressed because it is too large Load Diff
+5 -5
View File
@@ -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;