mirror of
https://github.com/odin-lang/Odin.git
synced 2026-05-09 14:14:22 +00:00
Merge pull request #2263 from odin-lang/compiler-improvements-2022-12
Compiler Improvements for 2022-12
This commit is contained in:
@@ -62,6 +62,7 @@ if %release_mode% EQU 0 ( rem Debug
|
||||
set compiler_warnings= ^
|
||||
-W4 -WX ^
|
||||
-wd4100 -wd4101 -wd4127 -wd4146 ^
|
||||
-wd4505 ^
|
||||
-wd4456 -wd4457
|
||||
|
||||
set compiler_includes= ^
|
||||
|
||||
152
src/array.cpp
152
src/array.cpp
@@ -10,45 +10,45 @@ struct Array {
|
||||
|
||||
T &operator[](isize index) {
|
||||
#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
|
||||
return data[index];
|
||||
}
|
||||
|
||||
T const &operator[](isize index) const {
|
||||
#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
|
||||
return data[index];
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T> void array_init (Array<T> *array, gbAllocator const &a);
|
||||
template <typename T> void array_init (Array<T> *array, gbAllocator const &a, isize count);
|
||||
template <typename T> void array_init (Array<T> *array, gbAllocator const &a, isize count, isize capacity);
|
||||
template <typename T> Array<T> array_make (gbAllocator const &a);
|
||||
template <typename T> Array<T> array_make (gbAllocator const &a, isize count);
|
||||
template <typename T> Array<T> array_make (gbAllocator const &a, isize count, isize capacity);
|
||||
template <typename T> Array<T> array_make_from_ptr (T *data, isize count, isize capacity);
|
||||
template <typename T> void array_free (Array<T> *array);
|
||||
template <typename T> void array_add (Array<T> *array, T const &t);
|
||||
template <typename T> T * array_add_and_get (Array<T> *array);
|
||||
template <typename T> void array_add_elems (Array<T> *array, T const *elems, isize elem_count);
|
||||
template <typename T> T array_pop (Array<T> *array);
|
||||
template <typename T> void array_clear (Array<T> *array);
|
||||
template <typename T> void array_reserve (Array<T> *array, isize capacity);
|
||||
template <typename T> void array_resize (Array<T> *array, isize count);
|
||||
template <typename T> void array_set_capacity (Array<T> *array, isize capacity);
|
||||
template <typename T> Array<T> array_slice (Array<T> const &array, isize lo, isize hi);
|
||||
template <typename T> Array<T> array_clone (gbAllocator const &a, Array<T> const &array);
|
||||
template <typename T> gb_internal void array_init (Array<T> *array, gbAllocator const &a);
|
||||
template <typename T> gb_internal void array_init (Array<T> *array, gbAllocator const &a, isize count);
|
||||
template <typename T> gb_internal void array_init (Array<T> *array, gbAllocator const &a, isize count, isize capacity);
|
||||
template <typename T> gb_internal Array<T> array_make (gbAllocator const &a);
|
||||
template <typename T> gb_internal Array<T> array_make (gbAllocator const &a, isize count);
|
||||
template <typename T> gb_internal Array<T> array_make (gbAllocator const &a, isize count, isize capacity);
|
||||
template <typename T> gb_internal Array<T> array_make_from_ptr (T *data, isize count, isize capacity);
|
||||
template <typename T> gb_internal void array_free (Array<T> *array);
|
||||
template <typename T> gb_internal void array_add (Array<T> *array, T const &t);
|
||||
template <typename T> gb_internal T * array_add_and_get (Array<T> *array);
|
||||
template <typename T> gb_internal void array_add_elems (Array<T> *array, T const *elems, isize elem_count);
|
||||
template <typename T> gb_internal T array_pop (Array<T> *array);
|
||||
template <typename T> gb_internal void array_clear (Array<T> *array);
|
||||
template <typename T> gb_internal void array_reserve (Array<T> *array, isize capacity);
|
||||
template <typename T> gb_internal void array_resize (Array<T> *array, isize count);
|
||||
template <typename T> gb_internal void array_set_capacity (Array<T> *array, isize capacity);
|
||||
template <typename T> gb_internal Array<T> array_slice (Array<T> const &array, isize lo, isize hi);
|
||||
template <typename T> gb_internal Array<T> array_clone (gbAllocator const &a, Array<T> const &array);
|
||||
|
||||
template <typename T> void array_ordered_remove (Array<T> *array, isize index);
|
||||
template <typename T> void array_unordered_remove(Array<T> *array, isize index);
|
||||
template <typename T> gb_internal void array_ordered_remove (Array<T> *array, isize index);
|
||||
template <typename T> gb_internal void array_unordered_remove(Array<T> *array, isize index);
|
||||
|
||||
template <typename T> void array_copy(Array<T> *array, Array<T> const &data, isize offset);
|
||||
template <typename T> void array_copy(Array<T> *array, Array<T> const &data, isize offset, isize count);
|
||||
template <typename T> gb_internal void array_copy(Array<T> *array, Array<T> const &data, isize offset);
|
||||
template <typename T> gb_internal void array_copy(Array<T> *array, Array<T> const &data, isize offset, isize count);
|
||||
|
||||
template <typename T> T *array_end_ptr(Array<T> *array);
|
||||
template <typename T> gb_internal T *array_end_ptr(Array<T> *array);
|
||||
|
||||
|
||||
template <typename T>
|
||||
@@ -56,27 +56,27 @@ struct Slice {
|
||||
T *data;
|
||||
isize count;
|
||||
|
||||
T &operator[](isize index) {
|
||||
gb_inline T &operator[](isize index) {
|
||||
#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
|
||||
return data[index];
|
||||
}
|
||||
|
||||
T const &operator[](isize index) const {
|
||||
gb_inline T const &operator[](isize index) const {
|
||||
#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
|
||||
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>
|
||||
Slice<T> slice_make(gbAllocator const &allocator, isize count) {
|
||||
gb_internal Slice<T> slice_make(gbAllocator const &allocator, isize count) {
|
||||
GB_ASSERT(count >= 0);
|
||||
Slice<T> s = {};
|
||||
s.data = gb_alloc_array(allocator, T, count);
|
||||
@@ -86,7 +86,7 @@ Slice<T> slice_make(gbAllocator const &allocator, isize count) {
|
||||
}
|
||||
|
||||
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);
|
||||
s->data = gb_alloc_array(allocator, T, count);
|
||||
if (count > 0) {
|
||||
@@ -96,23 +96,23 @@ void slice_init(Slice<T> *s, gbAllocator const &allocator, isize count) {
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
s->count = new_count;
|
||||
}
|
||||
|
||||
|
||||
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};
|
||||
}
|
||||
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);
|
||||
Slice<T> out = {};
|
||||
isize len = hi-lo;
|
||||
@@ -125,30 +125,30 @@ Slice<T> slice_array(Array<T> const &array, isize lo, isize hi) {
|
||||
|
||||
|
||||
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));
|
||||
return {data, a.count};
|
||||
}
|
||||
|
||||
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);
|
||||
return {c.data, c.count};
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
gb_memmove(slice->data, data.data, gb_size_of(T)*n);
|
||||
}
|
||||
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);
|
||||
gb_memmove(slice->data+offset, data.data, gb_size_of(T)*n);
|
||||
}
|
||||
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));
|
||||
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>
|
||||
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);
|
||||
Slice<T> out = {};
|
||||
isize len = hi-lo;
|
||||
@@ -169,7 +169,7 @@ gb_inline Slice<T> slice(Slice<T> const &array, isize lo, isize hi) {
|
||||
|
||||
|
||||
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);
|
||||
|
||||
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>
|
||||
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);
|
||||
|
||||
isize n = array->count-1;
|
||||
@@ -190,18 +190,18 @@ void slice_unordered_remove(Slice<T> *array, isize index) {
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
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));
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <typename T>
|
||||
T *array_end_ptr(Array<T> *array) {
|
||||
gb_internal T *array_end_ptr(Array<T> *array) {
|
||||
if (array->count > 0) {
|
||||
return &array->data[array->count-1];
|
||||
}
|
||||
@@ -210,18 +210,18 @@ T *array_end_ptr(Array<T> *array) {
|
||||
|
||||
|
||||
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);
|
||||
array_init(array, a, 0, cap);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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->data = nullptr;
|
||||
if (capacity > 0) {
|
||||
@@ -234,7 +234,7 @@ gb_inline void array_init(Array<T> *array, gbAllocator const &a, isize count, is
|
||||
|
||||
|
||||
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};
|
||||
a.data = data;
|
||||
a.count = count;
|
||||
@@ -244,7 +244,7 @@ gb_inline Array<T> array_make_from_ptr(T *data, isize count, isize capacity) {
|
||||
|
||||
|
||||
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);
|
||||
Array<T> array = {};
|
||||
array.allocator = a;
|
||||
@@ -254,7 +254,7 @@ gb_inline Array<T> array_make(gbAllocator const &a) {
|
||||
return array;
|
||||
}
|
||||
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.allocator = a;
|
||||
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;
|
||||
}
|
||||
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.allocator = a;
|
||||
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>
|
||||
gb_inline void array_free(Array<T> *array) {
|
||||
gb_internal gb_inline void array_free(Array<T> *array) {
|
||||
if (array->allocator.proc != nullptr) {
|
||||
gb_free(array->allocator, array->data);
|
||||
}
|
||||
@@ -284,7 +284,7 @@ gb_inline void array_free(Array<T> *array) {
|
||||
}
|
||||
|
||||
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);
|
||||
if (new_capacity < min_capacity) {
|
||||
new_capacity = min_capacity;
|
||||
@@ -293,7 +293,7 @@ void array__grow(Array<T> *array, isize min_capacity) {
|
||||
}
|
||||
|
||||
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) {
|
||||
array__grow(array, 0);
|
||||
}
|
||||
@@ -302,7 +302,7 @@ void array_add(Array<T> *array, T const &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) {
|
||||
return &array->data[array->count++];
|
||||
}
|
||||
@@ -314,7 +314,7 @@ T *array_add_and_get(Array<T> *array) {
|
||||
|
||||
|
||||
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);
|
||||
if (array->capacity < 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>
|
||||
gb_inline T array_pop(Array<T> *array) {
|
||||
gb_internal gb_inline T array_pop(Array<T> *array) {
|
||||
GB_ASSERT(array->count > 0);
|
||||
array->count--;
|
||||
return array->data[array->count];
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void array_clear(Array<T> *array) {
|
||||
gb_internal void array_clear(Array<T> *array) {
|
||||
array->count = 0;
|
||||
}
|
||||
|
||||
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) {
|
||||
array_set_capacity(array, capacity);
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
array__grow(array, count);
|
||||
}
|
||||
@@ -352,7 +352,7 @@ void array_resize(Array<T> *array, isize count) {
|
||||
}
|
||||
|
||||
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) {
|
||||
return;
|
||||
}
|
||||
@@ -381,7 +381,7 @@ void array_set_capacity(Array<T> *array, isize capacity) {
|
||||
|
||||
|
||||
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);
|
||||
Array<T> out = {};
|
||||
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>
|
||||
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);
|
||||
array_copy(&clone, array, 0);
|
||||
return clone;
|
||||
@@ -402,7 +402,7 @@ Array<T> array_clone(gbAllocator const &allocator, Array<T> const &array) {
|
||||
|
||||
|
||||
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);
|
||||
|
||||
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>
|
||||
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);
|
||||
|
||||
isize n = array->count-1;
|
||||
@@ -424,35 +424,35 @@ void array_unordered_remove(Array<T> *array, isize index) {
|
||||
|
||||
|
||||
template <typename T>
|
||||
T *begin(Array<T> &array) {
|
||||
gb_internal T *begin(Array<T> &array) {
|
||||
return array.data;
|
||||
}
|
||||
template <typename T>
|
||||
T const *begin(Array<T> const &array) {
|
||||
gb_internal T const *begin(Array<T> const &array) {
|
||||
return array.data;
|
||||
}
|
||||
template <typename T>
|
||||
T *end(Array<T> &array) {
|
||||
gb_internal T *end(Array<T> &array) {
|
||||
return array.data + array.count;
|
||||
}
|
||||
template <typename T>
|
||||
T const *end(Array<T> const &array) {
|
||||
gb_internal T const *end(Array<T> const &array) {
|
||||
return array.data + array.count;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T *begin(Slice<T> &array) {
|
||||
gb_internal T *begin(Slice<T> &array) {
|
||||
return array.data;
|
||||
}
|
||||
template <typename T>
|
||||
T const *begin(Slice<T> const &array) {
|
||||
gb_internal T const *begin(Slice<T> const &array) {
|
||||
return array.data;
|
||||
}
|
||||
template <typename T>
|
||||
T *end(Slice<T> &array) {
|
||||
gb_internal T *end(Slice<T> &array) {
|
||||
return array.data + array.count;
|
||||
}
|
||||
template <typename T>
|
||||
T const *end(Slice<T> const &array) {
|
||||
gb_internal T const *end(Slice<T> const &array) {
|
||||
return array.data + array.count;
|
||||
}
|
||||
|
||||
158
src/big_int.cpp
158
src/big_int.cpp
@@ -37,86 +37,86 @@ void MP_FREE(void *mem, size_t size) {
|
||||
|
||||
typedef mp_int BigInt;
|
||||
|
||||
void big_int_from_u64(BigInt *dst, u64 x);
|
||||
void big_int_from_i64(BigInt *dst, i64 x);
|
||||
void big_int_init (BigInt *dst, BigInt const *src);
|
||||
void big_int_from_string(BigInt *dst, String const &s, bool *success);
|
||||
gb_internal void big_int_from_u64(BigInt *dst, u64 x);
|
||||
gb_internal void big_int_from_i64(BigInt *dst, i64 x);
|
||||
gb_internal void big_int_init (BigInt *dst, BigInt const *src);
|
||||
gb_internal void big_int_from_string(BigInt *dst, String const &s, bool *success);
|
||||
|
||||
void big_int_dealloc(BigInt *dst) {
|
||||
gb_internal void big_int_dealloc(BigInt *dst) {
|
||||
mp_clear(dst);
|
||||
}
|
||||
|
||||
BigInt big_int_make(BigInt const *b, bool abs=false);
|
||||
BigInt big_int_make_abs(BigInt const *b);
|
||||
BigInt big_int_make_u64(u64 x);
|
||||
BigInt big_int_make_i64(i64 x);
|
||||
gb_internal BigInt big_int_make(BigInt const *b, bool abs=false);
|
||||
gb_internal BigInt big_int_make_abs(BigInt const *b);
|
||||
gb_internal BigInt big_int_make_u64(u64 x);
|
||||
gb_internal BigInt big_int_make_i64(i64 x);
|
||||
|
||||
u64 big_int_to_u64 (BigInt const *x);
|
||||
i64 big_int_to_i64 (BigInt const *x);
|
||||
f64 big_int_to_f64 (BigInt const *x);
|
||||
String big_int_to_string(gbAllocator allocator, BigInt const *x, u64 base = 10);
|
||||
gb_internal u64 big_int_to_u64 (BigInt const *x);
|
||||
gb_internal i64 big_int_to_i64 (BigInt const *x);
|
||||
gb_internal f64 big_int_to_f64 (BigInt const *x);
|
||||
gb_internal String big_int_to_string(gbAllocator allocator, BigInt const *x, u64 base = 10);
|
||||
|
||||
void big_int_add (BigInt *dst, BigInt const *x, BigInt const *y);
|
||||
void big_int_sub (BigInt *dst, BigInt const *x, BigInt const *y);
|
||||
void big_int_shl (BigInt *dst, BigInt const *x, BigInt const *y);
|
||||
void big_int_shr (BigInt *dst, BigInt const *x, BigInt const *y);
|
||||
void big_int_mul (BigInt *dst, BigInt const *x, BigInt const *y);
|
||||
void big_int_mul_u64(BigInt *dst, BigInt const *x, u64 y);
|
||||
gb_internal void big_int_add (BigInt *dst, BigInt const *x, BigInt const *y);
|
||||
gb_internal void big_int_sub (BigInt *dst, BigInt const *x, BigInt const *y);
|
||||
gb_internal void big_int_shl (BigInt *dst, BigInt const *x, BigInt const *y);
|
||||
gb_internal void big_int_shr (BigInt *dst, BigInt const *x, BigInt const *y);
|
||||
gb_internal void big_int_mul (BigInt *dst, BigInt const *x, BigInt const *y);
|
||||
gb_internal void big_int_mul_u64(BigInt *dst, BigInt const *x, u64 y);
|
||||
|
||||
void big_int_quo_rem(BigInt const *x, BigInt const *y, BigInt *q, BigInt *r);
|
||||
void big_int_quo (BigInt *z, BigInt const *x, BigInt const *y);
|
||||
void big_int_rem (BigInt *z, BigInt const *x, BigInt const *y);
|
||||
gb_internal void big_int_quo_rem(BigInt const *x, BigInt const *y, BigInt *q, BigInt *r);
|
||||
gb_internal void big_int_quo (BigInt *z, BigInt const *x, BigInt const *y);
|
||||
gb_internal void big_int_rem (BigInt *z, BigInt const *x, BigInt const *y);
|
||||
|
||||
void big_int_and (BigInt *dst, BigInt const *x, BigInt const *y);
|
||||
void big_int_and_not(BigInt *dst, BigInt const *x, BigInt const *y);
|
||||
void big_int_xor (BigInt *dst, BigInt const *x, BigInt const *y);
|
||||
void big_int_or (BigInt *dst, BigInt const *x, BigInt const *y);
|
||||
void big_int_not (BigInt *dst, BigInt const *x, i32 bit_count, bool is_signed);
|
||||
gb_internal void big_int_and (BigInt *dst, BigInt const *x, BigInt const *y);
|
||||
gb_internal void big_int_and_not(BigInt *dst, BigInt const *x, BigInt const *y);
|
||||
gb_internal void big_int_xor (BigInt *dst, BigInt const *x, BigInt const *y);
|
||||
gb_internal void big_int_or (BigInt *dst, BigInt const *x, BigInt const *y);
|
||||
gb_internal void big_int_not (BigInt *dst, BigInt const *x, i32 bit_count, bool is_signed);
|
||||
|
||||
|
||||
void big_int_add_eq(BigInt *dst, BigInt const *x);
|
||||
void big_int_sub_eq(BigInt *dst, BigInt const *x);
|
||||
void big_int_shl_eq(BigInt *dst, BigInt const *x);
|
||||
void big_int_shr_eq(BigInt *dst, BigInt const *x);
|
||||
void big_int_mul_eq(BigInt *dst, BigInt const *x);
|
||||
gb_internal void big_int_add_eq(BigInt *dst, BigInt const *x);
|
||||
gb_internal void big_int_sub_eq(BigInt *dst, BigInt const *x);
|
||||
gb_internal void big_int_shl_eq(BigInt *dst, BigInt const *x);
|
||||
gb_internal void big_int_shr_eq(BigInt *dst, BigInt const *x);
|
||||
gb_internal void big_int_mul_eq(BigInt *dst, BigInt const *x);
|
||||
|
||||
void big_int_quo_eq(BigInt *dst, BigInt const *x);
|
||||
void big_int_rem_eq(BigInt *dst, BigInt const *x);
|
||||
gb_internal void big_int_quo_eq(BigInt *dst, BigInt const *x);
|
||||
gb_internal void big_int_rem_eq(BigInt *dst, BigInt const *x);
|
||||
|
||||
bool big_int_is_neg(BigInt const *x);
|
||||
void big_int_neg(BigInt *dst, BigInt const *x);
|
||||
gb_internal bool big_int_is_neg(BigInt const *x);
|
||||
gb_internal void big_int_neg(BigInt *dst, BigInt const *x);
|
||||
|
||||
void big_int_add_eq(BigInt *dst, BigInt const *x) {
|
||||
gb_internal void big_int_add_eq(BigInt *dst, BigInt const *x) {
|
||||
BigInt res = {};
|
||||
big_int_init(&res, dst);
|
||||
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 = {};
|
||||
big_int_init(&res, dst);
|
||||
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 = {};
|
||||
big_int_init(&res, dst);
|
||||
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 = {};
|
||||
big_int_init(&res, dst);
|
||||
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 = {};
|
||||
big_int_init(&res, dst);
|
||||
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 = {};
|
||||
big_int_init(&res, dst);
|
||||
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 = {};
|
||||
big_int_init(&res, dst);
|
||||
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)) {
|
||||
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);
|
||||
}
|
||||
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);
|
||||
|
||||
}
|
||||
void big_int_init(BigInt *dst, BigInt const *src) {
|
||||
gb_internal void big_int_init(BigInt *dst, BigInt const *src) {
|
||||
if (dst == src) {
|
||||
return;
|
||||
}
|
||||
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 = {};
|
||||
big_int_init(&i, b);
|
||||
if (abs) mp_abs(&i, &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);
|
||||
}
|
||||
|
||||
|
||||
BigInt big_int_make_u64(u64 x) {
|
||||
gb_internal BigInt big_int_make_u64(u64 x) {
|
||||
BigInt i = {};
|
||||
big_int_from_u64(&i, x);
|
||||
return i;
|
||||
}
|
||||
BigInt big_int_make_i64(i64 x) {
|
||||
gb_internal BigInt big_int_make_i64(i64 x) {
|
||||
BigInt i = {};
|
||||
big_int_from_i64(&i, x);
|
||||
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;
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
f64 big_int_to_f64(BigInt const *x) {
|
||||
gb_internal f64 big_int_to_f64(BigInt const *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);
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
int big_int_cmp_zero(BigInt const *x) {
|
||||
gb_internal int big_int_cmp_zero(BigInt const *x) {
|
||||
if (mp_iszero(x)) {
|
||||
return 0;
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
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);
|
||||
BigInt d = {};
|
||||
mp_div_2d(x, yy, dst, &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 = {};
|
||||
big_int_from_u64(&d, y);
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
u64 leading_zeros_u64(u64 x) {
|
||||
gb_internal u64 leading_zeros_u64(u64 x) {
|
||||
#if defined(GB_COMPILER_MSVC)
|
||||
#if defined(GB_ARCH_64_BIT)
|
||||
return __lzcnt64(x);
|
||||
@@ -367,23 +367,23 @@ u64 leading_zeros_u64(u64 x) {
|
||||
//
|
||||
// q = x/y with the result truncated to zero
|
||||
// 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_);
|
||||
}
|
||||
|
||||
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 = {};
|
||||
big_int_quo_rem(x, y, z, &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 = {};
|
||||
big_int_quo_rem(x, y, &q, z);
|
||||
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 = {};
|
||||
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);
|
||||
}
|
||||
|
||||
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)) {
|
||||
big_int_init(dst, y);
|
||||
return;
|
||||
@@ -467,22 +467,22 @@ void big_int_and_not(BigInt *dst, BigInt const *x, BigInt const *y) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
if (bit_count == 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);
|
||||
}
|
||||
|
||||
bool big_int_is_neg(BigInt const *x) {
|
||||
gb_internal bool big_int_is_neg(BigInt const *x) {
|
||||
if (x == nullptr) {
|
||||
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);
|
||||
if (digit <= 9) {
|
||||
return digit + '0';
|
||||
@@ -548,7 +548,7 @@ char digit_to_char(u8 digit) {
|
||||
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);
|
||||
|
||||
if (mp_iszero(x)) {
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
NOTE(Jeroen): This prints the Windows product edition only, to be called from `print_platform_details`.
|
||||
*/
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
void report_windows_product_type(DWORD ProductType) {
|
||||
gb_internal void report_windows_product_type(DWORD ProductType) {
|
||||
switch (ProductType) {
|
||||
case PRODUCT_ULTIMATE:
|
||||
gb_printf("Ultimate");
|
||||
@@ -154,7 +154,7 @@ void report_windows_product_type(DWORD ProductType) {
|
||||
}
|
||||
#endif
|
||||
|
||||
void odin_cpuid(int leaf, int result[]) {
|
||||
gb_internal void odin_cpuid(int leaf, int result[]) {
|
||||
#if defined(GB_CPU_ARM)
|
||||
return;
|
||||
|
||||
@@ -169,7 +169,7 @@ void odin_cpuid(int leaf, int result[]) {
|
||||
#endif
|
||||
}
|
||||
|
||||
void report_cpu_info() {
|
||||
gb_internal void report_cpu_info() {
|
||||
gb_printf("\tCPU: ");
|
||||
|
||||
#if defined(GB_CPU_X86)
|
||||
@@ -220,7 +220,7 @@ void report_cpu_info() {
|
||||
/*
|
||||
Report the amount of installed RAM.
|
||||
*/
|
||||
void report_ram_info() {
|
||||
gb_internal void report_ram_info() {
|
||||
gb_printf("\tRAM: ");
|
||||
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
@@ -271,7 +271,7 @@ void report_ram_info() {
|
||||
#endif
|
||||
}
|
||||
|
||||
void report_os_info() {
|
||||
gb_internal void report_os_info() {
|
||||
gb_printf("\tOS: ");
|
||||
|
||||
#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.
|
||||
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("\tWebsite: https://odin-lang.org\n");
|
||||
gb_printf("\tGitHub: https://github.com/odin-lang/Odin/issues\n");
|
||||
|
||||
@@ -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("windows"),
|
||||
str_lit("darwin"),
|
||||
@@ -72,7 +72,7 @@ String target_os_names[TargetOs_COUNT] = {
|
||||
str_lit("freestanding"),
|
||||
};
|
||||
|
||||
String target_arch_names[TargetArch_COUNT] = {
|
||||
gb_global String target_arch_names[TargetArch_COUNT] = {
|
||||
str_lit(""),
|
||||
str_lit("amd64"),
|
||||
str_lit("i386"),
|
||||
@@ -82,19 +82,19 @@ String target_arch_names[TargetArch_COUNT] = {
|
||||
str_lit("wasm64"),
|
||||
};
|
||||
|
||||
String target_endian_names[TargetEndian_COUNT] = {
|
||||
gb_global String target_endian_names[TargetEndian_COUNT] = {
|
||||
str_lit(""),
|
||||
str_lit("little"),
|
||||
str_lit("big"),
|
||||
};
|
||||
|
||||
String target_abi_names[TargetABI_COUNT] = {
|
||||
gb_global String target_abi_names[TargetABI_COUNT] = {
|
||||
str_lit(""),
|
||||
str_lit("win64"),
|
||||
str_lit("sysv"),
|
||||
};
|
||||
|
||||
TargetEndianKind target_endians[TargetArch_COUNT] = {
|
||||
gb_global TargetEndianKind target_endians[TargetArch_COUNT] = {
|
||||
TargetEndian_Invalid,
|
||||
TargetEndian_Little,
|
||||
TargetEndian_Little,
|
||||
@@ -107,7 +107,7 @@ TargetEndianKind target_endians[TargetArch_COUNT] = {
|
||||
#define ODIN_VERSION_RAW "dev-unknown-unknown"
|
||||
#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_build = 1<<1,
|
||||
Command_check = 1<<3,
|
||||
Command_query = 1<<4,
|
||||
Command_doc = 1<<5,
|
||||
Command_version = 1<<6,
|
||||
Command_test = 1<<7,
|
||||
@@ -157,16 +156,15 @@ enum CommandKind : u32 {
|
||||
Command_strip_semicolon = 1<<8,
|
||||
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_all = ~(u32)0,
|
||||
};
|
||||
|
||||
char const *odin_command_strings[32] = {
|
||||
gb_global char const *odin_command_strings[32] = {
|
||||
"run",
|
||||
"build",
|
||||
"check",
|
||||
"query",
|
||||
"doc",
|
||||
"version",
|
||||
"test",
|
||||
@@ -316,8 +314,6 @@ struct BuildContext {
|
||||
u32 cmd_doc_flags;
|
||||
Array<String> extra_packages;
|
||||
|
||||
QueryDataSetSettings query_data_set_settings;
|
||||
|
||||
StringSet test_names;
|
||||
|
||||
gbAffinity affinity;
|
||||
@@ -333,10 +329,10 @@ struct BuildContext {
|
||||
|
||||
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;
|
||||
}
|
||||
bool global_ignore_warnings(void) {
|
||||
gb_internal bool global_ignore_warnings(void) {
|
||||
return build_context.ignore_warnings;
|
||||
}
|
||||
|
||||
@@ -398,7 +394,7 @@ gb_global TargetMetrics target_darwin_arm64 = {
|
||||
TargetArch_arm64,
|
||||
8, 8, 16,
|
||||
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 = {
|
||||
@@ -502,9 +498,9 @@ gb_global NamedTargetMetrics named_targets[] = {
|
||||
{ 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++) {
|
||||
if (str_eq_ignore_case(target_os_names[i], str)) {
|
||||
return cast(TargetOsKind)i;
|
||||
@@ -513,7 +509,7 @@ TargetOsKind get_target_os_from_string(String str) {
|
||||
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++) {
|
||||
if (str_eq_ignore_case(target_arch_names[i], str)) {
|
||||
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;
|
||||
name = remove_extension_from_path(name);
|
||||
|
||||
@@ -588,13 +584,12 @@ struct LibraryCollections {
|
||||
|
||||
gb_global Array<LibraryCollections> library_collections = {0};
|
||||
|
||||
void add_library_collection(String name, String path) {
|
||||
// TODO(bill): Check the path is valid and a directory
|
||||
gb_internal void add_library_collection(String name, String path) {
|
||||
LibraryCollections lc = {name, string_trim_whitespace(path)};
|
||||
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) {
|
||||
if (library_collections[i].name == name) {
|
||||
if (path) *path = library_collections[i].path;
|
||||
@@ -604,7 +599,7 @@ bool find_library_collection_path(String name, String *path) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool is_arch_wasm(void) {
|
||||
gb_internal bool is_arch_wasm(void) {
|
||||
switch (build_context.metrics.arch) {
|
||||
case TargetArch_wasm32:
|
||||
case TargetArch_wasm64:
|
||||
@@ -613,7 +608,7 @@ bool is_arch_wasm(void) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool is_arch_x86(void) {
|
||||
gb_internal bool is_arch_x86(void) {
|
||||
switch (build_context.metrics.arch) {
|
||||
case TargetArch_i386:
|
||||
case TargetArch_amd64:
|
||||
@@ -622,7 +617,7 @@ bool is_arch_x86(void) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool allow_check_foreign_filepath(void) {
|
||||
gb_internal bool allow_check_foreign_filepath(void) {
|
||||
switch (build_context.metrics.arch) {
|
||||
case TargetArch_wasm32:
|
||||
case TargetArch_wasm64:
|
||||
@@ -638,13 +633,14 @@ bool allow_check_foreign_filepath(void) {
|
||||
// is_abs_path
|
||||
// has_subdir
|
||||
|
||||
String const WIN32_SEPARATOR_STRING = {cast(u8 *)"\\", 1};
|
||||
String const NIX_SEPARATOR_STRING = {cast(u8 *)"/", 1};
|
||||
gb_global String const WIN32_SEPARATOR_STRING = {cast(u8 *)"\\", 1};
|
||||
gb_global String const NIX_SEPARATOR_STRING = {cast(u8 *)"/", 1};
|
||||
|
||||
String const WASM_MODULE_NAME_SEPARATOR = str_lit("..");
|
||||
gb_global String const WASM_MODULE_NAME_SEPARATOR = str_lit("..");
|
||||
|
||||
String internal_odin_root_dir(void);
|
||||
String odin_root_dir(void) {
|
||||
gb_internal String internal_odin_root_dir(void);
|
||||
|
||||
gb_internal String odin_root_dir(void) {
|
||||
if (global_module_path_set) {
|
||||
return global_module_path;
|
||||
}
|
||||
@@ -670,7 +666,7 @@ String odin_root_dir(void) {
|
||||
|
||||
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
String internal_odin_root_dir(void) {
|
||||
gb_internal String internal_odin_root_dir(void) {
|
||||
String path = global_module_path;
|
||||
isize len, i;
|
||||
wchar_t *text;
|
||||
@@ -723,9 +719,9 @@ String internal_odin_root_dir(void) {
|
||||
|
||||
#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;
|
||||
isize len, i;
|
||||
u8 *text;
|
||||
@@ -777,9 +773,9 @@ String internal_odin_root_dir(void) {
|
||||
// NOTE: Linux / Unix is unfinished and not tested very well.
|
||||
#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;
|
||||
isize len, i;
|
||||
u8 *text;
|
||||
@@ -938,7 +934,7 @@ String internal_odin_root_dir(void) {
|
||||
gb_global BlockingMutex fullpath_mutex;
|
||||
|
||||
#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 = {};
|
||||
mutex_lock(&fullpath_mutex);
|
||||
defer (mutex_unlock(&fullpath_mutex));
|
||||
@@ -965,7 +961,7 @@ String path_to_fullpath(gbAllocator a, String s) {
|
||||
return result;
|
||||
}
|
||||
#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;
|
||||
mutex_lock(&fullpath_mutex);
|
||||
p = realpath(cast(char *)s.text, 0);
|
||||
@@ -978,7 +974,7 @@ String path_to_fullpath(gbAllocator a, String s) {
|
||||
#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);
|
||||
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 core = str_lit("core/");
|
||||
@@ -1024,11 +1020,11 @@ String get_fullpath_core(gbAllocator a, String path) {
|
||||
return path_to_fullpath(a, res);
|
||||
}
|
||||
|
||||
bool show_error_line(void) {
|
||||
gb_internal bool show_error_line(void) {
|
||||
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);
|
||||
if (ext == ".asm") {
|
||||
return true;
|
||||
@@ -1041,7 +1037,7 @@ bool has_asm_extension(String const &path) {
|
||||
}
|
||||
|
||||
// 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);
|
||||
String file = get_file_path_string(pos.file_id);
|
||||
switch (build_context.ODIN_ERROR_POS_STYLE) {
|
||||
@@ -1056,7 +1052,7 @@ char *token_pos_to_string(TokenPos const &pos) {
|
||||
return s;
|
||||
}
|
||||
|
||||
void init_build_context(TargetMetrics *cross_target) {
|
||||
gb_internal void init_build_context(TargetMetrics *cross_target) {
|
||||
BuildContext *bc = &build_context;
|
||||
|
||||
gb_affinity_init(&bc->affinity);
|
||||
@@ -1258,7 +1254,7 @@ void init_build_context(TargetMetrics *cross_target) {
|
||||
#endif
|
||||
|
||||
|
||||
Array<String> split_by_comma(String const &list) {
|
||||
gb_internal Array<String> split_by_comma(String const &list) {
|
||||
isize n = 1;
|
||||
for (isize i = 0; i < list.len; i++) {
|
||||
if (list.text[i] == ',') {
|
||||
@@ -1280,12 +1276,12 @@ Array<String> split_by_comma(String const &list) {
|
||||
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
|
||||
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;
|
||||
mutex_lock(&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;
|
||||
}
|
||||
|
||||
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;
|
||||
mutex_lock(&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;
|
||||
for_array(i, build_context.target_features_set.entries) {
|
||||
isize i = 0;
|
||||
for (auto const &entry : build_context.target_features_set) {
|
||||
if (i != 0) {
|
||||
len += 1;
|
||||
}
|
||||
String feature = build_context.target_features_set.entries[i].value;
|
||||
String feature = entry.value;
|
||||
len += feature.len;
|
||||
if (with_quotes) len += 2;
|
||||
i += 1;
|
||||
}
|
||||
char *features = gb_alloc_array(allocator, char, len+1);
|
||||
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) {
|
||||
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);
|
||||
len += feature.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.
|
||||
// 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();
|
||||
BuildContext *bc = &build_context;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
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
|
||||
|
||||
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) {
|
||||
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 *right_type = nullptr;
|
||||
if (x->type->kind == Type_Tuple) {
|
||||
@@ -88,8 +88,7 @@ void check_or_else_split_types(CheckerContext *c, Operand *x, String const &name
|
||||
}
|
||||
|
||||
|
||||
void check_or_else_expr_no_value_error(CheckerContext *c, String const &name, Operand const &x, Type *type_hint) {
|
||||
// TODO(bill): better error message
|
||||
gb_internal void check_or_else_expr_no_value_error(CheckerContext *c, String const &name, Operand const &x, Type *type_hint) {
|
||||
gbString t = type_to_string(x.type);
|
||||
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))) {
|
||||
@@ -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 *right_type = nullptr;
|
||||
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) {
|
||||
return false;
|
||||
}
|
||||
@@ -165,7 +164,7 @@ bool does_require_msgSend_stret(Type *return_type) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ObjcMsgKind get_objc_proc_kind(Type *return_type) {
|
||||
gb_internal ObjcMsgKind get_objc_proc_kind(Type *return_type) {
|
||||
if (return_type == nullptr) {
|
||||
return ObjcMsg_normal;
|
||||
}
|
||||
@@ -189,7 +188,7 @@ ObjcMsgKind get_objc_proc_kind(Type *return_type) {
|
||||
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);
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
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 = {};
|
||||
check_expr(c, &op, expr);
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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 = {};
|
||||
check_expr_with_type_hint(c, &x, expr, t_atomic_memory_order);
|
||||
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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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(bd, BasicDirective, ce->proc);
|
||||
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) {
|
||||
return false;
|
||||
} else if (is_type_string(type)) {
|
||||
@@ -1191,7 +1190,7 @@ bool is_valid_type_for_load(Type *type) {
|
||||
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(bd, BasicDirective, ce->proc);
|
||||
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(bd, BasicDirective, ce->proc);
|
||||
String name = bd->name.string;
|
||||
@@ -1581,7 +1580,7 @@ bool check_builtin_procedure_directive(CheckerContext *c, Operand *operand, Ast
|
||||
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);
|
||||
if (ce->inlining != ProcInlining_none) {
|
||||
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)) {
|
||||
isize variable_count = type->Struct.fields.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);
|
||||
} else if (is_type_array(type)) {
|
||||
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));
|
||||
} else {
|
||||
array_add(&types, arg_type->Slice.elem);
|
||||
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));
|
||||
} else if (operand->value.kind == ExactValue_String) {
|
||||
String pkg_name = operand->value.value_string;
|
||||
// TODO(bill): probably should have this be a `StringMap` eventually
|
||||
for_array(i, c->info->packages.entries) {
|
||||
AstPackage *pkg = c->info->packages.entries[i].value;
|
||||
for (auto const &entry : c->info->packages) {
|
||||
AstPackage *pkg = entry.value;
|
||||
if (pkg->name == pkg_name) {
|
||||
value = true;
|
||||
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);
|
||||
GB_ASSERT(err == MP_OKAY);
|
||||
|
||||
if (id == BuiltinProc_reverse_bits) {
|
||||
// TODO(bill): Should this even be allowed at compile time?
|
||||
} else {
|
||||
if (id != BuiltinProc_reverse_bits) {
|
||||
u64 v = 0;
|
||||
switch (id) {
|
||||
case BuiltinProc_count_ones:
|
||||
|
||||
@@ -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
|
||||
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 ||
|
||||
operand->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);
|
||||
|
||||
// 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,
|
||||
"Cannot assign built-in procedure '%s' in %.*s",
|
||||
expr_str,
|
||||
@@ -110,7 +109,7 @@ Type *check_init_variable(CheckerContext *ctx, Entity *e, Operand *operand, Stri
|
||||
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) {
|
||||
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);
|
||||
|
||||
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);
|
||||
for (isize i = 0; i < max; 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 ||
|
||||
operand->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 (;;) {
|
||||
if (node == nullptr) {
|
||||
return false;
|
||||
@@ -217,7 +209,7 @@ bool is_type_distinct(Ast *node) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Ast *remove_type_alias_clutter(Ast *node) {
|
||||
gb_internal Ast *remove_type_alias_clutter(Ast *node) {
|
||||
for (;;) {
|
||||
if (node == nullptr) {
|
||||
return nullptr;
|
||||
@@ -232,17 +224,7 @@ Ast *remove_type_alias_clutter(Ast *node) {
|
||||
}
|
||||
}
|
||||
|
||||
isize total_attribute_count(DeclInfo *decl) {
|
||||
isize attribute_count = 0;
|
||||
for_array(i, decl->attributes) {
|
||||
Ast *attr = decl->attributes[i];
|
||||
if (attr->kind != Ast_Attribute) continue;
|
||||
attribute_count += attr->Attribute.elems.count;
|
||||
}
|
||||
return attribute_count;
|
||||
}
|
||||
|
||||
Type *clone_enum_type(CheckerContext *ctx, Type *original_enum_type, Type *named_type) {
|
||||
gb_internal Type *clone_enum_type(CheckerContext *ctx, Type *original_enum_type, Type *named_type) {
|
||||
// NOTE(bill, 2022-02-05): Stupid edge case for `distinct` declarations
|
||||
//
|
||||
// X :: enum {A, B, C}
|
||||
@@ -288,7 +270,7 @@ Type *clone_enum_type(CheckerContext *ctx, Type *original_enum_type, Type *named
|
||||
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);
|
||||
|
||||
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
|
||||
// e.g. file entity inserted into its package scope
|
||||
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->kind == Entity_Constant);
|
||||
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);
|
||||
bool sig_compare(TypeCheckSig *a, Type *x, Type *y) {
|
||||
gb_internal bool sig_compare(TypeCheckSig *a, Type *x, Type *y) {
|
||||
x = core_type(x);
|
||||
y = core_type(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);
|
||||
y = core_type(y);
|
||||
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)));
|
||||
}
|
||||
|
||||
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)) {
|
||||
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(b_->kind == Type_Proc);
|
||||
TypeProc *a = &a_->Proc;
|
||||
@@ -704,7 +686,7 @@ bool are_signatures_similar_enough(Type *a_, Type *b_) {
|
||||
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;
|
||||
Entity **foreign_library = nullptr;
|
||||
|
||||
@@ -747,7 +729,7 @@ Entity *init_entity_foreign_library(CheckerContext *ctx, Entity *e) {
|
||||
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_name.len > 0) {
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
if (d->proc_lit->kind != Ast_ProcLit) {
|
||||
// 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->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");
|
||||
}
|
||||
|
||||
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);
|
||||
auto *pge = &pg_entity->ProcGroup;
|
||||
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) {
|
||||
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) {
|
||||
return;
|
||||
}
|
||||
@@ -1499,8 +1481,8 @@ void check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *decl, Type *ty
|
||||
if (t->kind == Type_Struct) {
|
||||
Scope *scope = t->Struct.scope;
|
||||
GB_ASSERT(scope != nullptr);
|
||||
MUTEX_GUARD_BLOCK(scope->mutex) for_array(i, scope->elements.entries) {
|
||||
Entity *f = scope->elements.entries[i].value;
|
||||
MUTEX_GUARD_BLOCK(scope->mutex) for (auto const &entry : scope->elements) {
|
||||
Entity *f = entry.value;
|
||||
if (f->kind == Entity_Variable) {
|
||||
Entity *uvar = alloc_entity_using_variable(e, f->token, f->type, nullptr);
|
||||
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)
|
||||
// But only at the procedure level
|
||||
for_array(i, decl->deps.entries) {
|
||||
Entity *e = decl->deps.entries[i].ptr;
|
||||
for (auto const &entry : decl->deps) {
|
||||
Entity *e = entry.ptr;
|
||||
ptr_set_add(&decl->parent->deps, e);
|
||||
}
|
||||
for_array(i, decl->type_info_deps.entries) {
|
||||
Type *t = decl->type_info_deps.entries[i].ptr;
|
||||
for (auto const &entry : decl->type_info_deps) {
|
||||
Type *t = entry.ptr;
|
||||
ptr_set_add(&decl->parent->type_info_deps, t);
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
||||
bool is_diverging_expr(Ast *expr) {
|
||||
gb_internal bool is_diverging_expr(Ast *expr) {
|
||||
expr = unparen_expr(expr);
|
||||
if (expr->kind != Ast_CallExpr) {
|
||||
return false;
|
||||
@@ -23,14 +23,14 @@ bool is_diverging_expr(Ast *expr) {
|
||||
t = base_type(t);
|
||||
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) {
|
||||
return false;
|
||||
}
|
||||
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) {
|
||||
return true;
|
||||
}
|
||||
@@ -61,7 +61,7 @@ bool contains_deferred_call(Ast *node) {
|
||||
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) {
|
||||
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
|
||||
for (isize n = stmts.count-1; n >= 0; n--) {
|
||||
Ast *stmt = stmts[n];
|
||||
@@ -155,7 +155,7 @@ bool check_is_terminating_list(Slice<Ast *> const &stmts, String const &label) {
|
||||
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) {
|
||||
Ast *stmt = stmts[i];
|
||||
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) {
|
||||
case Ast_BranchStmt:
|
||||
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
|
||||
// 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) {
|
||||
case_ast_node(rs, ReturnStmt, node);
|
||||
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) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -477,8 +477,8 @@ Type *check_assignment_variable(CheckerContext *ctx, Operand *lhs, Operand *rhs)
|
||||
}
|
||||
|
||||
|
||||
void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags);
|
||||
void check_stmt(CheckerContext *ctx, Ast *node, u32 flags) {
|
||||
gb_internal void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags);
|
||||
gb_internal void check_stmt(CheckerContext *ctx, Ast *node, u32 flags) {
|
||||
u32 prev_state_flags = ctx->state_flags;
|
||||
|
||||
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};
|
||||
check_expr(ctx, &operand, ws->cond);
|
||||
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) {
|
||||
return;
|
||||
}
|
||||
@@ -582,7 +582,7 @@ void check_label(CheckerContext *ctx, Ast *label, Ast *parent) {
|
||||
}
|
||||
|
||||
// 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 (is_blank_ident(expr)) {
|
||||
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: {
|
||||
Scope *scope = e->ImportName.scope;
|
||||
MUTEX_GUARD_BLOCK(scope->mutex) for_array(i, scope->elements.entries) {
|
||||
String name = scope->elements.entries[i].key.string;
|
||||
Entity *decl = scope->elements.entries[i].value;
|
||||
MUTEX_GUARD_BLOCK(scope->mutex) for (auto const &entry : scope->elements) {
|
||||
String name = entry.key.string;
|
||||
Entity *decl = entry.value;
|
||||
if (!is_entity_exported(decl)) continue;
|
||||
|
||||
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) {
|
||||
Scope *found = t->Struct.scope;
|
||||
GB_ASSERT(found != nullptr);
|
||||
for_array(i, found->elements.entries) {
|
||||
Entity *f = found->elements.entries[i].value;
|
||||
for (auto const &entry : found->elements) {
|
||||
Entity *f = entry.value;
|
||||
if (f->kind == Entity_Variable) {
|
||||
Entity *uvar = alloc_entity_using_variable(e, f->token, f->type, expr);
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
Operand x = {};
|
||||
@@ -1092,7 +1092,7 @@ enum TypeSwitchKind {
|
||||
TypeSwitch_Any,
|
||||
};
|
||||
|
||||
TypeSwitchKind check_valid_type_switch_type(Type *type) {
|
||||
gb_internal TypeSwitchKind check_valid_type_switch_type(Type *type) {
|
||||
type = type_deref(type);
|
||||
if (is_type_union(type)) {
|
||||
return TypeSwitch_Union;
|
||||
@@ -1103,7 +1103,7 @@ TypeSwitchKind check_valid_type_switch_type(Type *type) {
|
||||
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);
|
||||
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");
|
||||
}
|
||||
|
||||
if (type_ptr_set_exists(&seen, y.type)) {
|
||||
if (type_ptr_set_update(&seen, y.type)) {
|
||||
TokenPos pos = cc->token.pos;
|
||||
gbString expr_str = expr_to_string(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);
|
||||
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) {
|
||||
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()) {
|
||||
for_array(i, operands) {
|
||||
if (operands[i].type == t_invalid) {
|
||||
@@ -1388,7 +1387,7 @@ bool all_operands_valid(Array<Operand> const &operands) {
|
||||
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;
|
||||
Entity *e = entity_of_node(expr);
|
||||
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;
|
||||
}
|
||||
|
||||
bool check_expr_is_stack_variable(Ast *expr) {
|
||||
gb_internal bool check_expr_is_stack_variable(Ast *expr) {
|
||||
/*
|
||||
expr = unparen_expr(expr);
|
||||
Entity *e = entity_of_node(expr);
|
||||
@@ -1419,7 +1418,7 @@ bool check_expr_is_stack_variable(Ast *expr) {
|
||||
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);
|
||||
switch (node->kind) {
|
||||
case_ast_node(_, EmptyStmt, node); case_end;
|
||||
@@ -1520,12 +1519,6 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) {
|
||||
}
|
||||
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);
|
||||
switch (as->op.kind) {
|
||||
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->flags |= EntityFlag_ForValue;
|
||||
entity->flags |= EntityFlag_Value;
|
||||
entity->identifier = name;
|
||||
if (i == addressable_index && use_by_reference_for_value) {
|
||||
entity->flags &= ~EntityFlag_Value;
|
||||
}
|
||||
@@ -1973,6 +1967,7 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) {
|
||||
|
||||
if (entity == nullptr) {
|
||||
entity = alloc_entity_dummy_variable(builtin_pkg->scope, ast_token(name));
|
||||
entity->identifier = name; // might not be an identifier
|
||||
}
|
||||
|
||||
array_add(&entities, entity);
|
||||
@@ -2370,8 +2365,8 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) {
|
||||
|
||||
Scope *scope = t->Struct.scope;
|
||||
GB_ASSERT(scope != nullptr);
|
||||
for_array(i, scope->elements.entries) {
|
||||
Entity *f = scope->elements.entries[i].value;
|
||||
for (auto const &entry : scope->elements) {
|
||||
Entity *f = entry.value;
|
||||
if (f->kind == Entity_Variable) {
|
||||
Entity *uvar = alloc_entity_using_variable(e, f->token, f->type, nullptr);
|
||||
uvar->flags |= (e->flags & EntityFlag_Value);
|
||||
|
||||
@@ -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);
|
||||
GB_ASSERT(t->kind == Type_Array);
|
||||
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) {
|
||||
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);
|
||||
if (is_type_struct(t)) {
|
||||
return true;
|
||||
@@ -91,8 +91,8 @@ bool does_field_type_allow_using(Type *t) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void check_struct_fields(CheckerContext *ctx, Ast *node, Slice<Entity *> *fields, String **tags, Slice<Ast *> const ¶ms,
|
||||
isize init_field_capacity, Type *struct_type, String context) {
|
||||
gb_internal void check_struct_fields(CheckerContext *ctx, Ast *node, Slice<Entity *> *fields, String **tags, Slice<Ast *> const ¶ms,
|
||||
isize init_field_capacity, Type *struct_type, String context) {
|
||||
auto fields_array = array_make<Entity *>(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);
|
||||
Operand o = {};
|
||||
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);
|
||||
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));
|
||||
gbAllocator a = heap_allocator();
|
||||
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);
|
||||
}
|
||||
|
||||
Type *check_record_polymorphic_params(CheckerContext *ctx, Ast *polymorphic_params,
|
||||
bool *is_polymorphic_,
|
||||
Ast *node, Array<Operand> *poly_operands,
|
||||
Type *named_type, Type *original_type_for_poly) {
|
||||
gb_internal Type *check_record_polymorphic_params(CheckerContext *ctx, Ast *polymorphic_params,
|
||||
bool *is_polymorphic_,
|
||||
Ast *node, Array<Operand> *poly_operands,
|
||||
Type *named_type, Type *original_type_for_poly) {
|
||||
Type *polymorphic_params_type = nullptr;
|
||||
bool can_check_fields = true;
|
||||
GB_ASSERT(is_polymorphic_ != nullptr);
|
||||
@@ -540,7 +540,7 @@ Type *check_record_polymorphic_params(CheckerContext *ctx, Ast *polymorphic_para
|
||||
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) {
|
||||
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));
|
||||
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));
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
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)) {
|
||||
return true;
|
||||
}
|
||||
@@ -861,7 +861,7 @@ bool is_type_valid_bit_set_range(Type *t) {
|
||||
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);
|
||||
GB_ASSERT(type->kind == Type_BitSet);
|
||||
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 ||
|
||||
type == t_invalid) {
|
||||
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 show_error = modify_type && !ctx->hide_polymorphic_errors;
|
||||
if (!is_operand_value(operand)) {
|
||||
@@ -1256,7 +1256,7 @@ Type *determine_type_from_polymorphic(CheckerContext *ctx, Type *poly_type, Oper
|
||||
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) {
|
||||
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 = {};
|
||||
param_value.original_ast_expr = expr;
|
||||
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) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -1791,8 +1791,8 @@ Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_params, bool *is
|
||||
|
||||
isize specialization_count = 0;
|
||||
if (scope != nullptr) {
|
||||
for_array(i, scope->elements.entries) {
|
||||
Entity *e = scope->elements.entries[i].value;
|
||||
for (auto const &entry : scope->elements) {
|
||||
Entity *e = entry.value;
|
||||
if (e->kind == Entity_TypeName) {
|
||||
Type *t = e->type;
|
||||
if (t->kind == Type_Generic &&
|
||||
@@ -1814,7 +1814,7 @@ Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_params, bool *is
|
||||
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) {
|
||||
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
|
||||
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);
|
||||
|
||||
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) {
|
||||
return 0;
|
||||
}
|
||||
@@ -2169,7 +2169,7 @@ i64 check_array_count(CheckerContext *ctx, Operand *o, Ast *e) {
|
||||
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();
|
||||
Type *t = alloc_type_tuple();
|
||||
slice_init(&t->Tuple.variables, a, 2);
|
||||
@@ -2185,7 +2185,7 @@ enum : i64 {
|
||||
MAP_CACHE_LINE_SIZE = 1 << MAP_CACHE_LINE_LOG2
|
||||
};
|
||||
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 len = 1;
|
||||
@@ -2197,7 +2197,7 @@ void map_cell_size_and_len(Type *type, i64 *size_, i64 *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(t_allocator != nullptr);
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
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");
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
if (e == nullptr) {
|
||||
*type = t_invalid;
|
||||
@@ -2997,7 +2997,7 @@ bool check_type_internal(CheckerContext *ctx, Ast *e, Type **type, Type *named_t
|
||||
return false;
|
||||
}
|
||||
|
||||
Type *check_type(CheckerContext *ctx, Ast *e) {
|
||||
gb_internal Type *check_type(CheckerContext *ctx, Ast *e) {
|
||||
CheckerContext c = *ctx;
|
||||
c.type_path = new_checker_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);
|
||||
}
|
||||
|
||||
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;
|
||||
bool ok = check_type_internal(ctx, e, &type, named_type);
|
||||
|
||||
|
||||
719
src/checker.cpp
719
src/checker.cpp
File diff suppressed because it is too large
Load Diff
@@ -20,7 +20,7 @@ struct ExprInfo {
|
||||
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);
|
||||
ei->mode = mode;
|
||||
ei->type = type;
|
||||
@@ -130,7 +130,7 @@ struct AttributeContext {
|
||||
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 = {};
|
||||
ac.link_prefix = link_prefix;
|
||||
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)
|
||||
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
|
||||
@@ -158,6 +158,7 @@ struct DeclInfo {
|
||||
bool is_using;
|
||||
bool where_clauses_evaluated;
|
||||
bool proc_checked;
|
||||
BlockingMutex proc_checked_mutex;
|
||||
isize defer_used;
|
||||
bool defer_use_checked;
|
||||
|
||||
@@ -377,15 +378,19 @@ struct CheckerInfo {
|
||||
};
|
||||
|
||||
struct CheckerContext {
|
||||
// Order matters here
|
||||
BlockingMutex mutex;
|
||||
Checker * checker;
|
||||
CheckerInfo * info;
|
||||
|
||||
AstPackage * pkg;
|
||||
AstFile * file;
|
||||
Scope * scope;
|
||||
DeclInfo * decl;
|
||||
|
||||
// Order doesn't matter after this
|
||||
u32 state_flags;
|
||||
bool in_defer; // TODO(bill): Actually handle correctly
|
||||
bool in_defer;
|
||||
Type * type_hint;
|
||||
|
||||
String proc_name;
|
||||
@@ -396,9 +401,7 @@ struct CheckerContext {
|
||||
ForeignContext foreign_context;
|
||||
|
||||
CheckerTypePath *type_path;
|
||||
isize type_level; // TODO(bill): Actually handle correctly
|
||||
CheckerPolyPath *poly_path;
|
||||
isize poly_level; // TODO(bill): Actually handle correctly
|
||||
isize type_level;
|
||||
|
||||
UntypedExprInfoMap *untyped;
|
||||
|
||||
@@ -443,59 +446,53 @@ gb_global AstPackage *config_pkg = nullptr;
|
||||
|
||||
|
||||
// CheckerInfo API
|
||||
TypeAndValue type_and_value_of_expr (Ast *expr);
|
||||
Type * type_of_expr (Ast *expr);
|
||||
Entity * implicit_entity_of_node(Ast *clause);
|
||||
DeclInfo * decl_info_of_ident (Ast *ident);
|
||||
DeclInfo * decl_info_of_entity (Entity * e);
|
||||
AstFile * ast_file_of_filename (CheckerInfo *i, String filename);
|
||||
gb_internal TypeAndValue type_and_value_of_expr (Ast *expr);
|
||||
gb_internal Type * type_of_expr (Ast *expr);
|
||||
gb_internal Entity * implicit_entity_of_node(Ast *clause);
|
||||
gb_internal DeclInfo * decl_info_of_ident (Ast *ident);
|
||||
gb_internal DeclInfo * decl_info_of_entity (Entity * e);
|
||||
gb_internal AstFile * ast_file_of_filename (CheckerInfo *i, String filename);
|
||||
// IMPORTANT: Only to use once checking is done
|
||||
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
|
||||
Entity *entity_of_node(Ast *expr);
|
||||
gb_internal Entity *entity_of_node(Ast *expr);
|
||||
|
||||
|
||||
Entity *scope_lookup_current(Scope *s, String const &name);
|
||||
Entity *scope_lookup (Scope *s, String const &name);
|
||||
void scope_lookup_parent (Scope *s, String const &name, Scope **scope_, Entity **entity_);
|
||||
Entity *scope_insert (Scope *s, Entity *entity, bool use_mutex=true);
|
||||
gb_internal Entity *scope_lookup_current(Scope *s, String const &name);
|
||||
gb_internal Entity *scope_lookup (Scope *s, String const &name);
|
||||
gb_internal void scope_lookup_parent (Scope *s, String const &name, Scope **scope_, Entity **entity_);
|
||||
gb_internal Entity *scope_insert (Scope *s, Entity *entity, bool use_mutex=true);
|
||||
|
||||
|
||||
void add_type_and_value (CheckerInfo *i, Ast *expression, AddressingMode mode, Type *type, ExactValue value);
|
||||
ExprInfo *check_get_expr_info (CheckerContext *c, Ast *expr);
|
||||
void add_untyped (CheckerContext *c, Ast *expression, AddressingMode mode, Type *basic_type, ExactValue value);
|
||||
void add_entity_use (CheckerContext *c, Ast *identifier, Entity *entity);
|
||||
void add_implicit_entity (CheckerContext *c, Ast *node, Entity *e);
|
||||
void add_entity_and_decl_info(CheckerContext *c, Ast *identifier, Entity *e, DeclInfo *d, bool is_exported=true);
|
||||
void add_type_info_type (CheckerContext *c, Type *t);
|
||||
gb_internal void add_type_and_value (CheckerInfo *i, Ast *expression, AddressingMode mode, Type *type, ExactValue value);
|
||||
gb_internal ExprInfo *check_get_expr_info (CheckerContext *c, Ast *expr);
|
||||
gb_internal void add_untyped (CheckerContext *c, Ast *expression, AddressingMode mode, Type *basic_type, ExactValue value);
|
||||
gb_internal void add_entity_use (CheckerContext *c, Ast *identifier, Entity *entity);
|
||||
gb_internal void add_implicit_entity (CheckerContext *c, Ast *node, Entity *e);
|
||||
gb_internal void add_entity_and_decl_info(CheckerContext *c, Ast *identifier, Entity *e, DeclInfo *d, bool is_exported=true);
|
||||
gb_internal void add_type_info_type (CheckerContext *c, Type *t);
|
||||
|
||||
void check_add_import_decl(CheckerContext *c, Ast *decl);
|
||||
void check_add_foreign_import_decl(CheckerContext *c, Ast *decl);
|
||||
gb_internal void check_add_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);
|
||||
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_entity_decl(CheckerContext *c, Entity *e, DeclInfo *d, Type *named_type);
|
||||
gb_internal void check_const_decl(CheckerContext *c, Entity *e, Ast *type_expr, Ast *init_expr, Type *named_type);
|
||||
gb_internal void check_type_decl(CheckerContext *c, Entity *e, Ast *type_expr, Type *def);
|
||||
|
||||
bool check_arity_match(CheckerContext *c, AstValueDecl *vd, bool is_global = false);
|
||||
void check_collect_entities(CheckerContext *c, Slice<Ast *> const &nodes);
|
||||
void check_collect_entities_from_when_stmt(CheckerContext *c, AstWhenStmt *ws);
|
||||
void check_delayed_file_import_entity(CheckerContext *c, Ast *decl);
|
||||
gb_internal bool check_arity_match(CheckerContext *c, AstValueDecl *vd, bool is_global = false);
|
||||
gb_internal void check_collect_entities(CheckerContext *c, Slice<Ast *> const &nodes);
|
||||
gb_internal void check_collect_entities_from_when_stmt(CheckerContext *c, AstWhenStmt *ws);
|
||||
gb_internal void check_delayed_file_import_entity(CheckerContext *c, Ast *decl);
|
||||
|
||||
CheckerTypePath *new_checker_type_path();
|
||||
void destroy_checker_type_path(CheckerTypePath *tp);
|
||||
gb_internal CheckerTypePath *new_checker_type_path();
|
||||
gb_internal void destroy_checker_type_path(CheckerTypePath *tp);
|
||||
|
||||
void check_type_path_push(CheckerContext *c, Entity *e);
|
||||
Entity *check_type_path_pop (CheckerContext *c);
|
||||
gb_internal void check_type_path_push(CheckerContext *c, Entity *e);
|
||||
gb_internal Entity *check_type_path_pop (CheckerContext *c);
|
||||
|
||||
CheckerPolyPath *new_checker_poly_path();
|
||||
void destroy_checker_poly_path(CheckerPolyPath *);
|
||||
gb_internal void init_core_context(Checker *c);
|
||||
gb_internal void init_mem_allocator(Checker *c);
|
||||
|
||||
void check_poly_path_push(CheckerContext *c, Type *t);
|
||||
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);
|
||||
gb_internal void add_untyped_expressions(CheckerInfo *cinfo, UntypedExprInfoMap *untyped);
|
||||
|
||||
@@ -29,14 +29,14 @@
|
||||
#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)
|
||||
|
||||
gbAllocator heap_allocator(void);
|
||||
gb_internal gbAllocator heap_allocator(void);
|
||||
|
||||
#define for_array(index_, array_) for (isize index_ = 0; index_ < (array_).count; index_++)
|
||||
|
||||
i32 next_pow2(i32 n);
|
||||
i64 next_pow2(i64 n);
|
||||
isize next_pow2_isize(isize n);
|
||||
void debugf(char const *fmt, ...);
|
||||
gb_internal i32 next_pow2(i32 n);
|
||||
gb_internal i64 next_pow2(i64 n);
|
||||
gb_internal isize next_pow2_isize(isize n);
|
||||
gb_internal void debugf(char const *fmt, ...);
|
||||
|
||||
#if defined(GB_SYSTEM_WINDOWS) && defined(GB_ARCH_32_BIT)
|
||||
#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 "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) {
|
||||
return false;
|
||||
}
|
||||
return !(x & (x-1));
|
||||
}
|
||||
|
||||
int isize_cmp(isize x, isize y) {
|
||||
gb_internal int isize_cmp(isize x, isize y) {
|
||||
if (x < y) {
|
||||
return -1;
|
||||
} else if (x > y) {
|
||||
@@ -66,7 +70,7 @@ int isize_cmp(isize x, isize y) {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int u64_cmp(u64 x, u64 y) {
|
||||
gb_internal int u64_cmp(u64 x, u64 y) {
|
||||
if (x < y) {
|
||||
return -1;
|
||||
} else if (x > y) {
|
||||
@@ -74,7 +78,7 @@ int u64_cmp(u64 x, u64 y) {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int i64_cmp(i64 x, i64 y) {
|
||||
gb_internal int i64_cmp(i64 x, i64 y) {
|
||||
if (x < y) {
|
||||
return -1;
|
||||
} else if (x > y) {
|
||||
@@ -82,7 +86,7 @@ int i64_cmp(i64 x, i64 y) {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int i32_cmp(i32 x, i32 y) {
|
||||
gb_internal int i32_cmp(i32 x, i32 y) {
|
||||
if (x < y) {
|
||||
return -1;
|
||||
} else if (x > y) {
|
||||
@@ -91,7 +95,7 @@ int i32_cmp(i32 x, i32 y) {
|
||||
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;
|
||||
u32 h = 0x811c9dc5;
|
||||
|
||||
@@ -112,7 +116,7 @@ u32 fnv32a(void const *data, isize len) {
|
||||
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;
|
||||
u64 h = 0xcbf29ce484222325ull;
|
||||
|
||||
@@ -133,7 +137,7 @@ u64 fnv64a(void const *data, isize len) {
|
||||
return h;
|
||||
}
|
||||
|
||||
u64 u64_digit_value(Rune r) {
|
||||
gb_internal u64 u64_digit_value(Rune r) {
|
||||
switch (r) {
|
||||
case '0': return 0;
|
||||
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;
|
||||
bool has_prefix = false;
|
||||
if (string.len > 2 && string[0] == '0') {
|
||||
@@ -205,7 +209,7 @@ gb_global char const global_num_to_char_table[] =
|
||||
"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};
|
||||
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);
|
||||
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};
|
||||
isize i = gb_size_of(buf);
|
||||
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;
|
||||
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;
|
||||
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)
|
||||
*lo = _umul128(x, y, hi);
|
||||
#else
|
||||
@@ -342,7 +346,7 @@ struct StringIntern {
|
||||
PtrMap<uintptr, StringIntern *> string_intern_map = {}; // Key: u64
|
||||
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);
|
||||
uintptr key = cast(uintptr)(hash ? hash : 1);
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void init_string_interner(void) {
|
||||
gb_internal void init_string_interner(void) {
|
||||
map_init(&string_intern_map, heap_allocator());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
i32 next_pow2(i32 n) {
|
||||
gb_internal i32 next_pow2(i32 n) {
|
||||
if (n <= 0) {
|
||||
return 0;
|
||||
}
|
||||
@@ -387,7 +391,7 @@ i32 next_pow2(i32 n) {
|
||||
n++;
|
||||
return n;
|
||||
}
|
||||
i64 next_pow2(i64 n) {
|
||||
gb_internal i64 next_pow2(i64 n) {
|
||||
if (n <= 0) {
|
||||
return 0;
|
||||
}
|
||||
@@ -401,7 +405,7 @@ i64 next_pow2(i64 n) {
|
||||
n++;
|
||||
return n;
|
||||
}
|
||||
isize next_pow2_isize(isize n) {
|
||||
gb_internal isize next_pow2_isize(isize n) {
|
||||
if (n <= 0) {
|
||||
return 0;
|
||||
}
|
||||
@@ -417,7 +421,7 @@ isize next_pow2_isize(isize n) {
|
||||
n++;
|
||||
return n;
|
||||
}
|
||||
u32 next_pow2_u32(u32 n) {
|
||||
gb_internal u32 next_pow2_u32(u32 n) {
|
||||
if (n == 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 >> 2) & 0x33333333) + (x & 0x33333333));
|
||||
x = (((x >> 4) + x) & 0x0f0f0f0f);
|
||||
@@ -442,13 +446,13 @@ i32 bit_set_count(u32 x) {
|
||||
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 b = *(cast(u32 *)&x + 1);
|
||||
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 >> 2;
|
||||
x |= x >> 4;
|
||||
@@ -457,7 +461,7 @@ u32 floor_log2(u32 x) {
|
||||
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 >> 2;
|
||||
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));
|
||||
y |= -y;
|
||||
y >>= 32-1;
|
||||
@@ -480,7 +484,7 @@ u32 ceil_log2(u32 x) {
|
||||
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));
|
||||
y |= -y;
|
||||
y >>= 64-1;
|
||||
@@ -493,7 +497,7 @@ u64 ceil_log2(u64 x) {
|
||||
return cast(u64)(bit_set_count(x) - 1 - y);
|
||||
}
|
||||
|
||||
u32 prev_pow2(u32 n) {
|
||||
gb_internal u32 prev_pow2(u32 n) {
|
||||
if (n == 0) {
|
||||
return 0;
|
||||
}
|
||||
@@ -504,7 +508,7 @@ u32 prev_pow2(u32 n) {
|
||||
n |= n >> 16;
|
||||
return n - (n >> 1);
|
||||
}
|
||||
i32 prev_pow2(i32 n) {
|
||||
gb_internal i32 prev_pow2(i32 n) {
|
||||
if (n <= 0) {
|
||||
return 0;
|
||||
}
|
||||
@@ -515,7 +519,7 @@ i32 prev_pow2(i32 n) {
|
||||
n |= n >> 16;
|
||||
return n - (n >> 1);
|
||||
}
|
||||
i64 prev_pow2(i64 n) {
|
||||
gb_internal i64 prev_pow2(i64 n) {
|
||||
if (n <= 0) {
|
||||
return 0;
|
||||
}
|
||||
@@ -528,7 +532,7 @@ i64 prev_pow2(i64 n) {
|
||||
return n - (n >> 1);
|
||||
}
|
||||
|
||||
u16 f32_to_f16(f32 value) {
|
||||
gb_internal u16 f32_to_f16(f32 value) {
|
||||
union { u32 i; f32 f; } v;
|
||||
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;
|
||||
fp32 v;
|
||||
|
||||
@@ -595,7 +599,7 @@ f32 f16_to_f32(u16 value) {
|
||||
return v.f;
|
||||
}
|
||||
|
||||
f64 gb_sqrt(f64 x) {
|
||||
gb_internal gb_inline f64 gb_sqrt(f64 x) {
|
||||
return sqrt(x);
|
||||
}
|
||||
|
||||
@@ -623,7 +627,7 @@ f64 gb_sqrt(f64 x) {
|
||||
|
||||
#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 len = cast(u32)string16_len(cmd_line);
|
||||
@@ -706,7 +710,7 @@ enum LoadedFileError {
|
||||
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;
|
||||
|
||||
if (!copy_file_contents) {
|
||||
@@ -811,7 +815,7 @@ LoadedFileError load_file_32(char const *fullpath, LoadedFile *memory_mapped_fil
|
||||
|
||||
#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 h = a.len+1;
|
||||
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};
|
||||
|
||||
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 = {};
|
||||
array_init(&d.distances, allocator, 0, cap);
|
||||
d.key = key;
|
||||
return d;
|
||||
}
|
||||
void did_you_mean_destroy(DidYouMeanAnswers *d) {
|
||||
gb_internal void did_you_mean_destroy(DidYouMeanAnswers *d) {
|
||||
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 == "_") {
|
||||
return;
|
||||
}
|
||||
@@ -888,7 +892,7 @@ void did_you_mean_append(DidYouMeanAnswers *d, String const &target) {
|
||||
dat.distance = levenstein_distance_case_insensitive(d->key, target);
|
||||
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)));
|
||||
isize count = 0;
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -7,27 +7,27 @@ gb_inline void zero_size(void *ptr, isize len) {
|
||||
|
||||
|
||||
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>
|
||||
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) {
|
||||
i64 result = size + align-1;
|
||||
return result - result%align;
|
||||
}
|
||||
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) {
|
||||
isize result = size + align-1;
|
||||
return result - result%align;
|
||||
}
|
||||
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) {
|
||||
uintptr result = (cast(uintptr)ptr) + align-1;
|
||||
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_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_allocator_mutex);
|
||||
platform_virtual_memory_init();
|
||||
@@ -66,13 +66,13 @@ enum { DEFAULT_MINIMUM_BLOCK_SIZE = 8ll*1024ll*1024ll };
|
||||
|
||||
gb_global isize DEFAULT_PAGE_SIZE = 4096;
|
||||
|
||||
MemoryBlock *virtual_memory_alloc(isize size);
|
||||
void virtual_memory_dealloc(MemoryBlock *block);
|
||||
void *arena_alloc(Arena *arena, isize min_size, isize alignment);
|
||||
void arena_free_all(Arena *arena);
|
||||
gb_internal MemoryBlock *virtual_memory_alloc(isize size);
|
||||
gb_internal void virtual_memory_dealloc(MemoryBlock *block);
|
||||
gb_internal void *arena_alloc(Arena *arena, isize min_size, isize alignment);
|
||||
gb_internal void arena_free_all(Arena *arena);
|
||||
|
||||
|
||||
isize arena_align_forward_offset(Arena *arena, isize alignment) {
|
||||
gb_internal isize arena_align_forward_offset(Arena *arena, isize alignment) {
|
||||
isize alignment_offset = 0;
|
||||
isize ptr = cast(isize)(arena->curr_block->base + arena->curr_block->used);
|
||||
isize mask = alignment-1;
|
||||
@@ -82,7 +82,7 @@ isize arena_align_forward_offset(Arena *arena, isize alignment) {
|
||||
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));
|
||||
|
||||
BlockingMutex *mutex = &global_memory_allocator_mutex;
|
||||
@@ -123,7 +123,7 @@ void *arena_alloc(Arena *arena, isize min_size, isize alignment) {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void arena_free_all(Arena *arena) {
|
||||
gb_internal void arena_free_all(Arena *arena) {
|
||||
while (arena->curr_block != nullptr) {
|
||||
MemoryBlock *free_block = arena->curr_block;
|
||||
arena->curr_block = free_block->prev;
|
||||
@@ -142,12 +142,12 @@ struct PlatformMemoryBlock {
|
||||
gb_global std::atomic<isize> global_platform_memory_total_usage;
|
||||
gb_global PlatformMemoryBlock global_platform_memory_block_sentinel;
|
||||
|
||||
PlatformMemoryBlock *platform_virtual_memory_alloc(isize total_size);
|
||||
void platform_virtual_memory_free(PlatformMemoryBlock *block);
|
||||
void platform_virtual_memory_protect(void *memory, isize size);
|
||||
gb_internal PlatformMemoryBlock *platform_virtual_memory_alloc(isize total_size);
|
||||
gb_internal void platform_virtual_memory_free(PlatformMemoryBlock *block);
|
||||
gb_internal void platform_virtual_memory_protect(void *memory, isize size);
|
||||
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
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.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));
|
||||
}
|
||||
|
||||
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);
|
||||
if (pmblock == nullptr) {
|
||||
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_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;
|
||||
}
|
||||
void platform_virtual_memory_free(PlatformMemoryBlock *block) {
|
||||
global_platform_memory_total_usage -= block->total_size;
|
||||
gb_internal void platform_virtual_memory_free(PlatformMemoryBlock *block) {
|
||||
global_platform_memory_total_usage.fetch_sub(block->total_size);
|
||||
GB_ASSERT(VirtualFree(block, 0, MEM_RELEASE));
|
||||
}
|
||||
void platform_virtual_memory_protect(void *memory, isize size) {
|
||||
gb_internal void platform_virtual_memory_protect(void *memory, isize size) {
|
||||
DWORD old_protect = 0;
|
||||
BOOL is_protected = VirtualProtect(memory, size, PAGE_NOACCESS, &old_protect);
|
||||
GB_ASSERT(is_protected);
|
||||
}
|
||||
#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.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));
|
||||
}
|
||||
|
||||
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);
|
||||
if (pmblock == nullptr) {
|
||||
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;
|
||||
return pmblock;
|
||||
}
|
||||
void platform_virtual_memory_free(PlatformMemoryBlock *block) {
|
||||
gb_internal void platform_virtual_memory_free(PlatformMemoryBlock *block) {
|
||||
isize size = block->total_size;
|
||||
global_platform_memory_total_usage -= 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);
|
||||
GB_ASSERT(err == 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
MemoryBlock *virtual_memory_alloc(isize size) {
|
||||
gb_internal MemoryBlock *virtual_memory_alloc(isize size) {
|
||||
isize const page_size = DEFAULT_PAGE_SIZE;
|
||||
|
||||
isize total_size = size + gb_size_of(PlatformMemoryBlock);
|
||||
@@ -250,7 +250,7 @@ MemoryBlock *virtual_memory_alloc(isize size) {
|
||||
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;
|
||||
if (block != nullptr) {
|
||||
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;
|
||||
a.proc = arena_allocator_proc;
|
||||
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;
|
||||
Arena *arena = cast(Arena *)allocator_data;
|
||||
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};
|
||||
gbAllocator permanent_allocator() {
|
||||
gb_internal gbAllocator permanent_allocator() {
|
||||
return arena_allocator(&permanent_arena);
|
||||
}
|
||||
|
||||
gbAllocator temporary_allocator() {
|
||||
gb_internal gbAllocator temporary_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;
|
||||
a.proc = heap_allocator_proc;
|
||||
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;
|
||||
gb_unused(allocator_data);
|
||||
gb_unused(old_size);
|
||||
@@ -460,7 +460,7 @@ GB_ALLOCATOR_PROC(heap_allocator_proc) {
|
||||
|
||||
|
||||
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);
|
||||
if (new_count == 0) {
|
||||
gb_free(a, *array);
|
||||
|
||||
36
src/docs.cpp
36
src/docs.cpp
@@ -28,7 +28,7 @@ gb_global char const *print_entity_names[Entity_Count] = {
|
||||
};
|
||||
|
||||
|
||||
GB_COMPARE_PROC(cmp_entities_for_printing) {
|
||||
gb_internal GB_COMPARE_PROC(cmp_entities_for_printing) {
|
||||
GB_ASSERT(a != nullptr);
|
||||
GB_ASSERT(b != nullptr);
|
||||
Entity *x = *cast(Entity **)a;
|
||||
@@ -56,7 +56,7 @@ GB_COMPARE_PROC(cmp_entities_for_printing) {
|
||||
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(b != nullptr);
|
||||
AstPackage *x = *cast(AstPackage **)a;
|
||||
@@ -67,7 +67,7 @@ GB_COMPARE_PROC(cmp_ast_package_by_name) {
|
||||
#include "docs_format.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) {
|
||||
gb_printf("\t");
|
||||
}
|
||||
@@ -75,7 +75,7 @@ void print_doc_line(i32 indent, String const &data) {
|
||||
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) {
|
||||
gb_printf("\t");
|
||||
}
|
||||
@@ -85,16 +85,7 @@ void print_doc_line(i32 indent, char const *fmt, ...) {
|
||||
va_end(va);
|
||||
gb_printf("\n");
|
||||
}
|
||||
void print_doc_line_no_newline(i32 indent, char const *fmt, ...) {
|
||||
while (indent --> 0) {
|
||||
gb_printf("\t");
|
||||
}
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
gb_printf_va(fmt, va);
|
||||
va_end(va);
|
||||
}
|
||||
void print_doc_line_no_newline(i32 indent, String const &data) {
|
||||
gb_internal void print_doc_line_no_newline(i32 indent, String const &data) {
|
||||
while (indent --> 0) {
|
||||
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) {
|
||||
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;
|
||||
if (build_context.cmd_doc_flags & CmdDocFlag_Short) {
|
||||
s = expr_to_string_shorthand(expr);
|
||||
@@ -202,8 +193,7 @@ void print_doc_expr(Ast *expr) {
|
||||
gb_string_free(s);
|
||||
}
|
||||
|
||||
|
||||
void print_doc_package(CheckerInfo *info, AstPackage *pkg) {
|
||||
gb_internal void print_doc_package(CheckerInfo *info, AstPackage *pkg) {
|
||||
if (pkg == nullptr) {
|
||||
return;
|
||||
}
|
||||
@@ -222,8 +212,8 @@ void print_doc_package(CheckerInfo *info, AstPackage *pkg) {
|
||||
if (pkg->scope != nullptr) {
|
||||
auto entities = array_make<Entity *>(heap_allocator(), 0, pkg->scope->elements.entries.count);
|
||||
defer (array_free(&entities));
|
||||
for_array(i, pkg->scope->elements.entries) {
|
||||
Entity *e = pkg->scope->elements.entries[i].value;
|
||||
for (auto const &entry : pkg->scope->elements) {
|
||||
Entity *e = entry.value;
|
||||
switch (e->kind) {
|
||||
case Entity_Invalid:
|
||||
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;
|
||||
|
||||
if (build_context.cmd_doc_flags & CmdDocFlag_DocFormat) {
|
||||
@@ -359,8 +349,8 @@ void generate_documentation(Checker *c) {
|
||||
odin_doc_write(info, output_file_path);
|
||||
} else {
|
||||
auto pkgs = array_make<AstPackage *>(permanent_allocator(), 0, info->packages.entries.count);
|
||||
for_array(i, info->packages.entries) {
|
||||
AstPackage *pkg = info->packages.entries[i].value;
|
||||
for (auto const &entry : info->packages) {
|
||||
AstPackage *pkg = entry.value;
|
||||
if (build_context.cmd_doc_flags & CmdDocFlag_AllPackages) {
|
||||
array_add(&pkgs, pkg);
|
||||
} else {
|
||||
|
||||
@@ -27,14 +27,14 @@ struct OdinDocHeaderBase {
|
||||
};
|
||||
|
||||
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 = {};
|
||||
s.data = cast(T *)(cast(uintptr)base + cast(uintptr)a.offset);
|
||||
s.count = cast(isize)a.length;
|
||||
return s;
|
||||
}
|
||||
|
||||
String from_string(OdinDocHeaderBase *base, OdinDocString const &s) {
|
||||
gb_internal String from_string(OdinDocHeaderBase *base, OdinDocString const &s) {
|
||||
String str = {};
|
||||
str.text = cast(u8 *)(cast(uintptr)base + cast(uintptr)s.offset);
|
||||
str.len = cast(isize)s.length;
|
||||
|
||||
@@ -11,7 +11,7 @@ enum OdinDocWriterState {
|
||||
OdinDocWriterState_Writing,
|
||||
};
|
||||
|
||||
char const* OdinDocWriterState_strings[] {
|
||||
gb_global char const* OdinDocWriterState_strings[] {
|
||||
"preparing",
|
||||
"writing ",
|
||||
};
|
||||
@@ -40,17 +40,17 @@ struct OdinDocWriter {
|
||||
OdinDocWriterItemTracker<u8> blob;
|
||||
};
|
||||
|
||||
OdinDocEntityIndex odin_doc_add_entity(OdinDocWriter *w, Entity *e);
|
||||
OdinDocTypeIndex odin_doc_type(OdinDocWriter *w, Type *type);
|
||||
gb_internal OdinDocEntityIndex odin_doc_add_entity(OdinDocWriter *w, Entity *e);
|
||||
gb_internal OdinDocTypeIndex odin_doc_type(OdinDocWriter *w, Type *type);
|
||||
|
||||
template <typename T>
|
||||
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->cap = size;
|
||||
}
|
||||
|
||||
|
||||
void odin_doc_writer_prepare(OdinDocWriter *w) {
|
||||
gb_internal void odin_doc_writer_prepare(OdinDocWriter *w) {
|
||||
w->state = OdinDocWriterState_Preparing;
|
||||
|
||||
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);
|
||||
|
||||
string_map_destroy(&w->string_cache);
|
||||
@@ -83,7 +83,7 @@ void odin_doc_writer_destroy(OdinDocWriter *w) {
|
||||
|
||||
|
||||
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 align = gb_max(gb_align_of(T), alignment);
|
||||
*offset = align_formula_isize(*offset, align);
|
||||
@@ -91,7 +91,7 @@ void odin_doc_writer_tracker_size(isize *offset, OdinDocWriterItemTracker<T> *t,
|
||||
*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);
|
||||
odin_doc_writer_tracker_size(&total_size, &w->files);
|
||||
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;
|
||||
}
|
||||
|
||||
void odin_doc_writer_start_writing(OdinDocWriter *w) {
|
||||
gb_internal void odin_doc_writer_start_writing(OdinDocWriter *w) {
|
||||
w->state = OdinDocWriterState_Writing;
|
||||
|
||||
string_map_clear(&w->string_cache);
|
||||
@@ -118,7 +118,7 @@ void odin_doc_writer_start_writing(OdinDocWriter *w) {
|
||||
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 *end = start + base->total_size;
|
||||
start += base->header_size;
|
||||
@@ -132,13 +132,13 @@ u32 hash_data_after_header(OdinDocHeaderBase *base, void *data, isize data_len)
|
||||
|
||||
|
||||
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->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;
|
||||
|
||||
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>
|
||||
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) {
|
||||
t->cap += 1;
|
||||
if (dst) *dst = nullptr;
|
||||
@@ -175,7 +175,7 @@ u32 odin_doc_write_item(OdinDocWriter *w, OdinDocWriterItemTracker<T> *t, T cons
|
||||
}
|
||||
|
||||
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) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -184,7 +184,7 @@ T *odin_doc_get_item(OdinDocWriter *w, OdinDocWriterItemTracker<T> *t, u32 index
|
||||
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 = {};
|
||||
|
||||
if (w->state == OdinDocWriterState_Preparing) {
|
||||
@@ -204,7 +204,7 @@ OdinDocString odin_doc_write_string_without_cache(OdinDocWriter *w, String const
|
||||
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);
|
||||
if (c != nullptr) {
|
||||
if (w->state == OdinDocWriterState_Writing) {
|
||||
@@ -223,7 +223,7 @@ OdinDocString odin_doc_write_string(OdinDocWriter *w, String const &str) {
|
||||
|
||||
|
||||
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);
|
||||
if (len <= 0) {
|
||||
return {0, 0};
|
||||
@@ -249,12 +249,12 @@ OdinDocArray<T> odin_write_slice(OdinDocWriter *w, T *data, isize len) {
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
if (pos.file_id != 0) {
|
||||
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;
|
||||
}
|
||||
|
||||
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) {
|
||||
return false;
|
||||
}
|
||||
@@ -361,7 +361,7 @@ bool odin_doc_append_comment_group_string(Array<u8> *buf, CommentGroup *g) {
|
||||
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) {
|
||||
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));
|
||||
}
|
||||
|
||||
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) {
|
||||
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));
|
||||
}
|
||||
|
||||
OdinDocString odin_doc_expr_string(OdinDocWriter *w, Ast *expr) {
|
||||
gb_internal OdinDocString odin_doc_expr_string(OdinDocWriter *w, Ast *expr) {
|
||||
if (expr == nullptr) {
|
||||
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)));
|
||||
}
|
||||
|
||||
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;
|
||||
for_array(i, attributes) {
|
||||
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);
|
||||
}
|
||||
|
||||
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) {
|
||||
return {};
|
||||
}
|
||||
@@ -462,17 +462,17 @@ OdinDocArray<OdinDocString> odin_doc_where_clauses(OdinDocWriter *w, Slice<Ast *
|
||||
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);
|
||||
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);
|
||||
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) {
|
||||
return 0;
|
||||
}
|
||||
@@ -480,11 +480,11 @@ OdinDocTypeIndex odin_doc_type(OdinDocWriter *w, Type *type) {
|
||||
if (found) {
|
||||
return *found;
|
||||
}
|
||||
for_array(i, w->type_cache.entries) {
|
||||
for (auto const &entry : w->type_cache) {
|
||||
// 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)) {
|
||||
OdinDocTypeIndex index = w->type_cache.entries[i].value;
|
||||
OdinDocTypeIndex index = entry.value;
|
||||
map_set(&w->type_cache, type, index);
|
||||
return index;
|
||||
}
|
||||
@@ -750,7 +750,7 @@ OdinDocTypeIndex odin_doc_type(OdinDocWriter *w, Type *type) {
|
||||
}
|
||||
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) {
|
||||
return 0;
|
||||
}
|
||||
@@ -911,26 +911,24 @@ OdinDocEntityIndex odin_doc_add_entity(OdinDocWriter *w, Entity *e) {
|
||||
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
|
||||
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));
|
||||
|
||||
for_array(i, w->entity_cache.entries) {
|
||||
Entity *e = w->entity_cache.entries[i].key;
|
||||
entities[i] = e;
|
||||
for (auto const &entry : w->entity_cache) {
|
||||
array_add(&entities, entry.key);
|
||||
}
|
||||
for_array(i, entities) {
|
||||
Entity *e = entities[i];
|
||||
for (Entity *e : entities) {
|
||||
OdinDocTypeIndex type_index = odin_doc_type(w, e->type);
|
||||
gb_unused(type_index);
|
||||
}
|
||||
}
|
||||
|
||||
for_array(i, w->entity_cache.entries) {
|
||||
Entity *e = w->entity_cache.entries[i].key;
|
||||
OdinDocEntityIndex entity_index = w->entity_cache.entries[i].value;
|
||||
for (auto const &entry : w->entity_cache) {
|
||||
Entity *e = entry.key;
|
||||
OdinDocEntityIndex entity_index = entry.value;
|
||||
OdinDocTypeIndex type_index = odin_doc_type(w, e->type);
|
||||
|
||||
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);
|
||||
defer (array_free(&pges));
|
||||
|
||||
for_array(j, e->ProcGroup.entities) {
|
||||
OdinDocEntityIndex index = odin_doc_add_entity(w, e->ProcGroup.entities[j]);
|
||||
for (Entity *entity : e->ProcGroup.entities) {
|
||||
OdinDocEntityIndex index = odin_doc_add_entity(w, entity);
|
||||
array_add(&pges, index);
|
||||
}
|
||||
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) {
|
||||
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);
|
||||
defer (array_free(&entries));
|
||||
|
||||
for_array(i, pkg->scope->elements.entries) {
|
||||
String name = pkg->scope->elements.entries[i].key.string;
|
||||
Entity *e = pkg->scope->elements.entries[i].value;
|
||||
for (auto const &element : pkg->scope->elements) {
|
||||
String name = element.key.string;
|
||||
Entity *e = element.value;
|
||||
switch (e->kind) {
|
||||
case Entity_Invalid:
|
||||
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);
|
||||
defer (array_free(&pkgs));
|
||||
for_array(i, w->info->packages.entries) {
|
||||
AstPackage *pkg = w->info->packages.entries[i].value;
|
||||
for (auto const &entry : w->info->packages) {
|
||||
AstPackage *pkg = entry.value;
|
||||
if (build_context.cmd_doc_flags & CmdDocFlag_AllPackages) {
|
||||
array_add(&pkgs, pkg);
|
||||
} 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 = {};
|
||||
gbFileError err = gb_file_open_mode(&f, gbFileMode_Write, filename);
|
||||
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 = &w_;
|
||||
defer (odin_doc_writer_destroy(w));
|
||||
|
||||
@@ -26,7 +26,7 @@ enum EntityKind {
|
||||
Entity_Count,
|
||||
};
|
||||
|
||||
String const entity_strings[] = {
|
||||
gb_global String const entity_strings[] = {
|
||||
#define ENTITY_KIND(k) {cast(u8 *)#k, gb_size_of(#k)-1},
|
||||
ENTITY_KINDS
|
||||
#undef ENTITY_KIND
|
||||
@@ -116,7 +116,7 @@ struct ParameterValue {
|
||||
};
|
||||
};
|
||||
|
||||
bool has_parameter_value(ParameterValue const ¶m_value) {
|
||||
gb_internal gb_inline bool has_parameter_value(ParameterValue const ¶m_value) {
|
||||
if (param_value.kind != ParameterValue_Invalid) {
|
||||
return true;
|
||||
}
|
||||
@@ -151,7 +151,7 @@ struct TypeNameObjCMetadata {
|
||||
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);
|
||||
md->mutex = gb_alloc_item(permanent_allocator(), BlockingMutex);
|
||||
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) {
|
||||
case Entity_Builtin:
|
||||
return allow_builtin;
|
||||
@@ -278,7 +278,7 @@ bool is_entity_kind_exported(EntityKind kind, bool allow_builtin = false) {
|
||||
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
|
||||
GB_ASSERT(e != nullptr);
|
||||
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;
|
||||
}
|
||||
|
||||
bool entity_has_deferred_procedure(Entity *e) {
|
||||
gb_internal bool entity_has_deferred_procedure(Entity *e) {
|
||||
GB_ASSERT(e != nullptr);
|
||||
if (e->kind == Entity_Procedure) {
|
||||
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;
|
||||
|
||||
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();
|
||||
Entity *entity = gb_alloc_item(a, Entity);
|
||||
entity->kind = kind;
|
||||
@@ -323,13 +323,13 @@ Entity *alloc_entity(EntityKind kind, Scope *scope, Token token, Type *type) {
|
||||
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->state = state;
|
||||
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);
|
||||
token.pos = parent->token.pos;
|
||||
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->Constant.value = value;
|
||||
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->state = state;
|
||||
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->flags |= EntityFlag_Used;
|
||||
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->flags |= EntityFlag_Used;
|
||||
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->Variable.field_index = field_index;
|
||||
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;
|
||||
}
|
||||
|
||||
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->Variable.field_index = field_index;
|
||||
entity->flags |= EntityFlag_Field;
|
||||
@@ -393,26 +393,18 @@ Entity *alloc_entity_array_elem(Scope *scope, Token token, Type *type, i32 field
|
||||
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->Procedure.tags = tags;
|
||||
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);
|
||||
return entity;
|
||||
}
|
||||
|
||||
|
||||
Entity *alloc_entity_builtin(Scope *scope, Token token, Type *type, i32 id) {
|
||||
Entity *entity = alloc_entity(Entity_Builtin, scope, token, type);
|
||||
entity->Builtin.id = id;
|
||||
entity->state = EntityState_Resolved;
|
||||
return entity;
|
||||
}
|
||||
|
||||
Entity *alloc_entity_import_name(Scope *scope, Token token, Type *type,
|
||||
gb_internal Entity *alloc_entity_import_name(Scope *scope, Token token, Type *type,
|
||||
String path, String name, Scope *import_scope) {
|
||||
Entity *entity = alloc_entity(Entity_ImportName, scope, token, type);
|
||||
entity->ImportName.path = path;
|
||||
@@ -422,7 +414,7 @@ Entity *alloc_entity_import_name(Scope *scope, Token token, Type *type,
|
||||
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) {
|
||||
Entity *entity = alloc_entity(Entity_LibraryName, scope, token, type);
|
||||
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);
|
||||
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->Label.node = node;
|
||||
entity->Label.parent = parent;
|
||||
@@ -448,15 +440,15 @@ Entity *alloc_entity_label(Scope *scope, Token token, Type *type, Ast *node, Ast
|
||||
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("_");
|
||||
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) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -469,7 +461,7 @@ Entity *strip_entity_wrapping(Entity *e) {
|
||||
return e;
|
||||
}
|
||||
|
||||
Entity *strip_entity_wrapping(Ast *expr) {
|
||||
gb_internal Entity *strip_entity_wrapping(Ast *expr) {
|
||||
Entity *e = entity_from_expr(expr);
|
||||
return strip_entity_wrapping(e);
|
||||
}
|
||||
|
||||
@@ -17,11 +17,11 @@ gb_global ErrorCollector global_error_collector;
|
||||
#define MAX_ERROR_COLLECTOR_COUNT (36)
|
||||
|
||||
|
||||
bool any_errors(void) {
|
||||
gb_internal bool any_errors(void) {
|
||||
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.block_mutex);
|
||||
mutex_init(&global_error_collector.error_out_mutex);
|
||||
@@ -35,9 +35,9 @@ void init_global_error_collector(void) {
|
||||
|
||||
// temporary
|
||||
// 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;
|
||||
GB_ASSERT(index >= 0);
|
||||
mutex_lock(&global_error_collector.string_mutex);
|
||||
@@ -55,7 +55,7 @@ bool set_file_path_string(i32 index, String const &path) {
|
||||
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;
|
||||
GB_ASSERT(index >= 0);
|
||||
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;
|
||||
}
|
||||
|
||||
String get_file_path_string(i32 index) {
|
||||
gb_internal String get_file_path_string(i32 index) {
|
||||
GB_ASSERT(index >= 0);
|
||||
mutex_lock(&global_error_collector.string_mutex);
|
||||
|
||||
@@ -86,7 +86,7 @@ String get_file_path_string(i32 index) {
|
||||
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);
|
||||
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);
|
||||
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) {
|
||||
isize n = global_error_collector.error_buffer.count;
|
||||
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)
|
||||
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);
|
||||
|
||||
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
|
||||
bool global_warnings_as_errors(void);
|
||||
bool global_ignore_warnings(void);
|
||||
bool show_error_line(void);
|
||||
gbString get_file_line_as_string(TokenPos const &pos, i32 *offset);
|
||||
gb_internal bool global_warnings_as_errors(void);
|
||||
gb_internal bool global_ignore_warnings(void);
|
||||
gb_internal bool show_error_line(void);
|
||||
gb_internal gbString get_file_line_as_string(TokenPos const &pos, i32 *offset);
|
||||
|
||||
void error_out(char const *fmt, ...) {
|
||||
gb_internal void error_out(char const *fmt, ...) {
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
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()) {
|
||||
return false;
|
||||
}
|
||||
@@ -237,7 +237,7 @@ bool show_error_on_line(TokenPos const &pos, TokenPos end) {
|
||||
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);
|
||||
|
||||
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()) {
|
||||
error_va(pos, end, fmt, va);
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
global_error_collector.count++;
|
||||
// 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);
|
||||
global_error_collector.count++;
|
||||
// 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()) {
|
||||
syntax_error_va(pos, end, fmt, va);
|
||||
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_start(va, fmt);
|
||||
warning_va(token.pos, {}, fmt, 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_start(va, fmt);
|
||||
error_va(token.pos, {}, fmt, va);
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
void error(TokenPos pos, char const *fmt, ...) {
|
||||
gb_internal void error(TokenPos pos, char const *fmt, ...) {
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
Token token = {};
|
||||
@@ -370,7 +370,7 @@ void error(TokenPos pos, char const *fmt, ...) {
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
void error_line(char const *fmt, ...) {
|
||||
gb_internal void error_line(char const *fmt, ...) {
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
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_start(va, fmt);
|
||||
syntax_error_va(token.pos, {}, fmt, 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_start(va, fmt);
|
||||
syntax_error_va(pos, {}, fmt, 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_start(va, fmt);
|
||||
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_start(va, fmt);
|
||||
|
||||
@@ -6,7 +6,7 @@ struct Ast;
|
||||
struct HashKey;
|
||||
struct Type;
|
||||
struct Entity;
|
||||
bool are_types_identical(Type *x, Type *y);
|
||||
gb_internal bool are_types_identical(Type *x, Type *y);
|
||||
|
||||
struct Complex128 {
|
||||
f64 real, imag;
|
||||
@@ -15,16 +15,6 @@ struct Quaternion256 {
|
||||
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 {
|
||||
ExactValue_Invalid = 0,
|
||||
|
||||
@@ -60,7 +50,7 @@ struct ExactValue {
|
||||
|
||||
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);
|
||||
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};
|
||||
result.value_compound = node;
|
||||
return result;
|
||||
}
|
||||
|
||||
ExactValue exact_value_bool(bool b) {
|
||||
gb_internal ExactValue exact_value_bool(bool b) {
|
||||
ExactValue result = {ExactValue_Bool};
|
||||
result.value_bool = (b != 0);
|
||||
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
|
||||
ExactValue result = {ExactValue_String};
|
||||
result.value_string = string;
|
||||
return result;
|
||||
}
|
||||
|
||||
ExactValue exact_value_i64(i64 i) {
|
||||
gb_internal ExactValue exact_value_i64(i64 i) {
|
||||
ExactValue result = {ExactValue_Integer};
|
||||
big_int_from_i64(&result.value_integer, i);
|
||||
return result;
|
||||
}
|
||||
|
||||
ExactValue exact_value_u64(u64 i) {
|
||||
gb_internal ExactValue exact_value_u64(u64 i) {
|
||||
ExactValue result = {ExactValue_Integer};
|
||||
big_int_from_u64(&result.value_integer, i);
|
||||
return result;
|
||||
}
|
||||
|
||||
ExactValue exact_value_float(f64 f) {
|
||||
gb_internal ExactValue exact_value_float(f64 f) {
|
||||
ExactValue result = {ExactValue_Float};
|
||||
result.value_float = f;
|
||||
return result;
|
||||
}
|
||||
|
||||
ExactValue exact_value_complex(f64 real, f64 imag) {
|
||||
gb_internal ExactValue exact_value_complex(f64 real, f64 imag) {
|
||||
ExactValue result = {ExactValue_Complex};
|
||||
result.value_complex = gb_alloc_item(permanent_allocator(), Complex128);
|
||||
result.value_complex->real = real;
|
||||
@@ -142,7 +132,7 @@ ExactValue exact_value_complex(f64 real, f64 imag) {
|
||||
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};
|
||||
result.value_quaternion = gb_alloc_item(permanent_allocator(), Quaternion256);
|
||||
result.value_quaternion->real = real;
|
||||
@@ -152,27 +142,27 @@ ExactValue exact_value_quaternion(f64 real, f64 imag, f64 jmag, f64 kmag) {
|
||||
return result;
|
||||
}
|
||||
|
||||
ExactValue exact_value_pointer(i64 ptr) {
|
||||
gb_internal ExactValue exact_value_pointer(i64 ptr) {
|
||||
ExactValue result = {ExactValue_Pointer};
|
||||
result.value_pointer = ptr;
|
||||
return result;
|
||||
}
|
||||
|
||||
ExactValue exact_value_procedure(Ast *node) {
|
||||
gb_internal ExactValue exact_value_procedure(Ast *node) {
|
||||
ExactValue result = {ExactValue_Procedure};
|
||||
result.value_procedure = node;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
ExactValue exact_value_typeid(Type *type) {
|
||||
gb_internal ExactValue exact_value_typeid(Type *type) {
|
||||
ExactValue result = {ExactValue_Typeid};
|
||||
result.value_typeid = type;
|
||||
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};
|
||||
bool 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;
|
||||
u8 *str = string.text;
|
||||
isize len = string.len;
|
||||
@@ -262,7 +252,7 @@ f64 float_from_string(String string) {
|
||||
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') {
|
||||
|
||||
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) {
|
||||
case Token_String: return exact_value_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;
|
||||
}
|
||||
|
||||
ExactValue exact_value_to_integer(ExactValue v) {
|
||||
gb_internal ExactValue exact_value_to_integer(ExactValue v) {
|
||||
switch (v.kind) {
|
||||
case ExactValue_Bool: {
|
||||
i64 i = 0;
|
||||
@@ -357,7 +347,7 @@ ExactValue exact_value_to_integer(ExactValue v) {
|
||||
return r;
|
||||
}
|
||||
|
||||
ExactValue exact_value_to_float(ExactValue v) {
|
||||
gb_internal ExactValue exact_value_to_float(ExactValue v) {
|
||||
switch (v.kind) {
|
||||
case ExactValue_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;
|
||||
}
|
||||
|
||||
ExactValue exact_value_to_complex(ExactValue v) {
|
||||
gb_internal ExactValue exact_value_to_complex(ExactValue v) {
|
||||
switch (v.kind) {
|
||||
case ExactValue_Integer:
|
||||
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);
|
||||
return r;
|
||||
}
|
||||
ExactValue exact_value_to_quaternion(ExactValue v) {
|
||||
gb_internal ExactValue exact_value_to_quaternion(ExactValue v) {
|
||||
switch (v.kind) {
|
||||
case ExactValue_Integer:
|
||||
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;
|
||||
}
|
||||
|
||||
ExactValue exact_value_real(ExactValue v) {
|
||||
gb_internal ExactValue exact_value_real(ExactValue v) {
|
||||
switch (v.kind) {
|
||||
case ExactValue_Integer:
|
||||
case ExactValue_Float:
|
||||
@@ -413,7 +403,7 @@ ExactValue exact_value_real(ExactValue v) {
|
||||
return r;
|
||||
}
|
||||
|
||||
ExactValue exact_value_imag(ExactValue v) {
|
||||
gb_internal ExactValue exact_value_imag(ExactValue v) {
|
||||
switch (v.kind) {
|
||||
case ExactValue_Integer:
|
||||
case ExactValue_Float:
|
||||
@@ -427,7 +417,7 @@ ExactValue exact_value_imag(ExactValue v) {
|
||||
return r;
|
||||
}
|
||||
|
||||
ExactValue exact_value_jmag(ExactValue v) {
|
||||
gb_internal ExactValue exact_value_jmag(ExactValue v) {
|
||||
switch (v.kind) {
|
||||
case ExactValue_Integer:
|
||||
case ExactValue_Float:
|
||||
@@ -440,7 +430,7 @@ ExactValue exact_value_jmag(ExactValue v) {
|
||||
return r;
|
||||
}
|
||||
|
||||
ExactValue exact_value_kmag(ExactValue v) {
|
||||
gb_internal ExactValue exact_value_kmag(ExactValue v) {
|
||||
switch (v.kind) {
|
||||
case ExactValue_Integer:
|
||||
case ExactValue_Float:
|
||||
@@ -453,60 +443,60 @@ ExactValue exact_value_kmag(ExactValue v) {
|
||||
return r;
|
||||
}
|
||||
|
||||
ExactValue exact_value_make_imag(ExactValue v) {
|
||||
switch (v.kind) {
|
||||
case ExactValue_Integer:
|
||||
return exact_value_complex(0, exact_value_to_float(v).value_float);
|
||||
case ExactValue_Float:
|
||||
return exact_value_complex(0, v.value_float);
|
||||
default:
|
||||
GB_PANIC("Expected an integer or float type for 'exact_value_make_imag'");
|
||||
}
|
||||
ExactValue r = {ExactValue_Invalid};
|
||||
return r;
|
||||
}
|
||||
// gb_internal ExactValue exact_value_make_imag(ExactValue v) {
|
||||
// switch (v.kind) {
|
||||
// case ExactValue_Integer:
|
||||
// return exact_value_complex(0, exact_value_to_float(v).value_float);
|
||||
// case ExactValue_Float:
|
||||
// return exact_value_complex(0, v.value_float);
|
||||
// default:
|
||||
// GB_PANIC("Expected an integer or float type for 'exact_value_make_imag'");
|
||||
// }
|
||||
// ExactValue r = {ExactValue_Invalid};
|
||||
// return r;
|
||||
// }
|
||||
|
||||
ExactValue exact_value_make_jmag(ExactValue v) {
|
||||
switch (v.kind) {
|
||||
case ExactValue_Integer:
|
||||
return exact_value_quaternion(0, 0, exact_value_to_float(v).value_float, 0);
|
||||
case ExactValue_Float:
|
||||
return exact_value_quaternion(0, 0, v.value_float, 0);
|
||||
default:
|
||||
GB_PANIC("Expected an integer or float type for 'exact_value_make_imag'");
|
||||
}
|
||||
ExactValue r = {ExactValue_Invalid};
|
||||
return r;
|
||||
}
|
||||
// gb_internal ExactValue exact_value_make_jmag(ExactValue v) {
|
||||
// switch (v.kind) {
|
||||
// case ExactValue_Integer:
|
||||
// return exact_value_quaternion(0, 0, exact_value_to_float(v).value_float, 0);
|
||||
// case ExactValue_Float:
|
||||
// return exact_value_quaternion(0, 0, v.value_float, 0);
|
||||
// default:
|
||||
// GB_PANIC("Expected an integer or float type for 'exact_value_make_jmag'");
|
||||
// }
|
||||
// ExactValue r = {ExactValue_Invalid};
|
||||
// return r;
|
||||
// }
|
||||
|
||||
ExactValue exact_value_make_kmag(ExactValue v) {
|
||||
switch (v.kind) {
|
||||
case ExactValue_Integer:
|
||||
return exact_value_quaternion(0, 0, 0, exact_value_to_float(v).value_float);
|
||||
case ExactValue_Float:
|
||||
return exact_value_quaternion(0, 0, 0, v.value_float);
|
||||
default:
|
||||
GB_PANIC("Expected an integer or float type for 'exact_value_make_imag'");
|
||||
}
|
||||
ExactValue r = {ExactValue_Invalid};
|
||||
return r;
|
||||
}
|
||||
// gb_internal ExactValue exact_value_make_kmag(ExactValue v) {
|
||||
// switch (v.kind) {
|
||||
// case ExactValue_Integer:
|
||||
// return exact_value_quaternion(0, 0, 0, exact_value_to_float(v).value_float);
|
||||
// case ExactValue_Float:
|
||||
// return exact_value_quaternion(0, 0, 0, v.value_float);
|
||||
// default:
|
||||
// GB_PANIC("Expected an integer or float type for 'exact_value_make_kmag'");
|
||||
// }
|
||||
// ExactValue r = {ExactValue_Invalid};
|
||||
// return r;
|
||||
// }
|
||||
|
||||
i64 exact_value_to_i64(ExactValue v) {
|
||||
gb_internal i64 exact_value_to_i64(ExactValue v) {
|
||||
v = exact_value_to_integer(v);
|
||||
if (v.kind == ExactValue_Integer) {
|
||||
return big_int_to_i64(&v.value_integer);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
u64 exact_value_to_u64(ExactValue v) {
|
||||
gb_internal u64 exact_value_to_u64(ExactValue v) {
|
||||
v = exact_value_to_integer(v);
|
||||
if (v.kind == ExactValue_Integer) {
|
||||
return big_int_to_u64(&v.value_integer);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
f64 exact_value_to_f64(ExactValue v) {
|
||||
gb_internal f64 exact_value_to_f64(ExactValue v) {
|
||||
v = exact_value_to_float(v);
|
||||
if (v.kind == ExactValue_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) {
|
||||
case Token_Add: {
|
||||
switch (v.kind) {
|
||||
@@ -596,7 +586,7 @@ failure:
|
||||
}
|
||||
|
||||
// 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) {
|
||||
case ExactValue_Invalid:
|
||||
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)) {
|
||||
match_exact_values(y, x);
|
||||
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?
|
||||
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);
|
||||
|
||||
switch (x.kind) {
|
||||
@@ -846,32 +836,32 @@ error:; // NOTE(bill): MSVC accepts this??? apparently you cannot declare variab
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
|
||||
i32 cmp_f64(f64 a, f64 b) {
|
||||
gb_internal gb_inline i32 cmp_f64(f64 a, f64 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);
|
||||
|
||||
switch (x.kind) {
|
||||
@@ -969,12 +959,12 @@ bool compare_exact_values(TokenKind op, ExactValue x, ExactValue y) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Entity *strip_entity_wrapping(Ast *expr);
|
||||
Entity *strip_entity_wrapping(Entity *e);
|
||||
gb_internal Entity *strip_entity_wrapping(Ast *expr);
|
||||
gb_internal Entity *strip_entity_wrapping(Entity *e);
|
||||
|
||||
gbString write_expr_to_string(gbString str, Ast *node, bool shorthand);
|
||||
gb_internal gbString write_expr_to_string(gbString str, Ast *node, bool shorthand);
|
||||
|
||||
gbString write_exact_value_to_string(gbString str, ExactValue const &v, isize string_limit=36) {
|
||||
gb_internal gbString write_exact_value_to_string(gbString str, ExactValue const &v, isize string_limit=36) {
|
||||
switch (v.kind) {
|
||||
case ExactValue_Invalid:
|
||||
return str;
|
||||
@@ -1017,6 +1007,6 @@ gbString write_exact_value_to_string(gbString str, ExactValue const &v, isize st
|
||||
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);
|
||||
}
|
||||
|
||||
154
src/llvm_abi.cpp
154
src/llvm_abi.cpp
@@ -18,21 +18,21 @@ struct lbArgType {
|
||||
};
|
||||
|
||||
|
||||
i64 lb_sizeof(LLVMTypeRef type);
|
||||
i64 lb_alignof(LLVMTypeRef type);
|
||||
gb_internal i64 lb_sizeof(LLVMTypeRef type);
|
||||
gb_internal i64 lb_alignof(LLVMTypeRef type);
|
||||
|
||||
lbArgType lb_arg_type_direct(LLVMTypeRef type, LLVMTypeRef cast_type, LLVMTypeRef pad_type, LLVMAttributeRef attr) {
|
||||
gb_internal lbArgType lb_arg_type_direct(LLVMTypeRef type, LLVMTypeRef cast_type, LLVMTypeRef pad_type, LLVMAttributeRef attr) {
|
||||
return lbArgType{lbArg_Direct, type, cast_type, pad_type, attr, nullptr, 0, false};
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
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};
|
||||
}
|
||||
|
||||
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);
|
||||
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};
|
||||
}
|
||||
|
||||
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};
|
||||
}
|
||||
|
||||
@@ -55,24 +55,24 @@ struct lbFunctionType {
|
||||
isize original_arg_count;
|
||||
};
|
||||
|
||||
gbAllocator lb_function_type_args_allocator(void) {
|
||||
gb_internal gbAllocator lb_function_type_args_allocator(void) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
bool lb_is_type_kind(LLVMTypeRef type, LLVMTypeKind kind) {
|
||||
gb_internal bool lb_is_type_kind(LLVMTypeRef type, LLVMTypeKind kind) {
|
||||
if (type == nullptr) {
|
||||
return false;
|
||||
}
|
||||
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 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) {
|
||||
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);
|
||||
switch (kind) {
|
||||
case LLVMVoidTypeKind:
|
||||
@@ -267,7 +267,7 @@ i64 lb_sizeof(LLVMTypeRef type) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
i64 lb_alignof(LLVMTypeRef type) {
|
||||
gb_internal i64 lb_alignof(LLVMTypeRef type) {
|
||||
LLVMTypeKind kind = LLVMGetTypeKind(type);
|
||||
switch (kind) {
|
||||
case LLVMVoidTypeKind:
|
||||
@@ -333,7 +333,7 @@ typedef LB_ABI_INFO(lbAbiInfoType);
|
||||
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(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
|
||||
namespace lbAbi386 {
|
||||
Array<lbArgType> compute_arg_types(LLVMContextRef c, LLVMTypeRef *arg_types, unsigned arg_count);
|
||||
LB_ABI_COMPUTE_RETURN_TYPE(compute_return_type);
|
||||
gb_internal Array<lbArgType> compute_arg_types(LLVMContextRef c, LLVMTypeRef *arg_types, unsigned arg_count);
|
||||
gb_internal LB_ABI_COMPUTE_RETURN_TYPE(compute_return_type);
|
||||
|
||||
LB_ABI_INFO(abi_info) {
|
||||
gb_internal LB_ABI_INFO(abi_info) {
|
||||
lbFunctionType *ft = gb_alloc_item(permanent_allocator(), lbFunctionType);
|
||||
ft->ctx = c;
|
||||
ft->args = compute_arg_types(c, arg_types, arg_count);
|
||||
@@ -382,7 +382,7 @@ namespace lbAbi386 {
|
||||
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) {
|
||||
return lb_arg_type_indirect(type, nullptr);
|
||||
}
|
||||
@@ -409,7 +409,7 @@ namespace lbAbi386 {
|
||||
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);
|
||||
|
||||
for (unsigned i = 0; i < arg_count; i++) {
|
||||
@@ -429,7 +429,7 @@ namespace lbAbi386 {
|
||||
return args;
|
||||
}
|
||||
|
||||
LB_ABI_COMPUTE_RETURN_TYPE(compute_return_type) {
|
||||
gb_internal LB_ABI_COMPUTE_RETURN_TYPE(compute_return_type) {
|
||||
if (!return_is_defined) {
|
||||
return lb_arg_type_direct(LLVMVoidTypeInContext(c));
|
||||
} else if (lb_is_type_kind(return_type, LLVMStructTypeKind) || lb_is_type_kind(return_type, LLVMArrayTypeKind)) {
|
||||
@@ -451,10 +451,10 @@ namespace lbAbi386 {
|
||||
};
|
||||
|
||||
namespace lbAbiAmd64Win64 {
|
||||
Array<lbArgType> compute_arg_types(LLVMContextRef c, LLVMTypeRef *arg_types, unsigned arg_count);
|
||||
LB_ABI_COMPUTE_RETURN_TYPE(compute_return_type);
|
||||
gb_internal Array<lbArgType> compute_arg_types(LLVMContextRef c, LLVMTypeRef *arg_types, unsigned arg_count);
|
||||
gb_internal LB_ABI_COMPUTE_RETURN_TYPE(compute_return_type);
|
||||
|
||||
LB_ABI_INFO(abi_info) {
|
||||
gb_internal LB_ABI_INFO(abi_info) {
|
||||
lbFunctionType *ft = gb_alloc_item(permanent_allocator(), lbFunctionType);
|
||||
ft->ctx = c;
|
||||
ft->args = compute_arg_types(c, arg_types, arg_count);
|
||||
@@ -463,7 +463,7 @@ namespace lbAbiAmd64Win64 {
|
||||
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);
|
||||
|
||||
for (unsigned i = 0; i < arg_count; i++) {
|
||||
@@ -489,7 +489,7 @@ namespace lbAbiAmd64Win64 {
|
||||
return args;
|
||||
}
|
||||
|
||||
LB_ABI_COMPUTE_RETURN_TYPE(compute_return_type) {
|
||||
gb_internal LB_ABI_COMPUTE_RETURN_TYPE(compute_return_type) {
|
||||
if (!return_is_defined) {
|
||||
return lb_arg_type_direct(LLVMVoidTypeInContext(c));
|
||||
} else if (lb_is_type_kind(return_type, LLVMStructTypeKind) || lb_is_type_kind(return_type, LLVMArrayTypeKind)) {
|
||||
@@ -530,7 +530,7 @@ namespace lbAbiAmd64SysV {
|
||||
RegClass_Memory,
|
||||
};
|
||||
|
||||
bool is_sse(RegClass reg_class) {
|
||||
gb_internal bool is_sse(RegClass reg_class) {
|
||||
switch (reg_class) {
|
||||
case RegClass_SSEFs:
|
||||
case RegClass_SSEFv:
|
||||
@@ -546,7 +546,7 @@ namespace lbAbiAmd64SysV {
|
||||
return false;
|
||||
}
|
||||
|
||||
void all_mem(Array<RegClass> *cs) {
|
||||
gb_internal void all_mem(Array<RegClass> *cs) {
|
||||
for_array(i, *cs) {
|
||||
(*cs)[i] = RegClass_Memory;
|
||||
}
|
||||
@@ -558,14 +558,14 @@ namespace lbAbiAmd64SysV {
|
||||
Amd64TypeAttribute_StructRect,
|
||||
};
|
||||
|
||||
LB_ABI_COMPUTE_RETURN_TYPE(compute_return_type);
|
||||
void classify_with(LLVMTypeRef t, Array<RegClass> *cls, i64 ix, i64 off);
|
||||
void fixup(LLVMTypeRef t, Array<RegClass> *cls);
|
||||
lbArgType amd64_type(LLVMContextRef c, LLVMTypeRef type, Amd64TypeAttributeKind attribute_kind, ProcCallingConvention calling_convention);
|
||||
Array<RegClass> classify(LLVMTypeRef t);
|
||||
LLVMTypeRef llreg(LLVMContextRef c, Array<RegClass> const ®_classes);
|
||||
gb_internal LB_ABI_COMPUTE_RETURN_TYPE(compute_return_type);
|
||||
gb_internal void classify_with(LLVMTypeRef t, Array<RegClass> *cls, i64 ix, i64 off);
|
||||
gb_internal void fixup(LLVMTypeRef t, Array<RegClass> *cls);
|
||||
gb_internal lbArgType amd64_type(LLVMContextRef c, LLVMTypeRef type, Amd64TypeAttributeKind attribute_kind, ProcCallingConvention calling_convention);
|
||||
gb_internal Array<RegClass> classify(LLVMTypeRef t);
|
||||
gb_internal LLVMTypeRef llreg(LLVMContextRef c, Array<RegClass> const ®_classes);
|
||||
|
||||
LB_ABI_INFO(abi_info) {
|
||||
gb_internal LB_ABI_INFO(abi_info) {
|
||||
lbFunctionType *ft = gb_alloc_item(permanent_allocator(), lbFunctionType);
|
||||
ft->ctx = c;
|
||||
ft->calling_convention = calling_convention;
|
||||
@@ -584,7 +584,7 @@ namespace lbAbiAmd64SysV {
|
||||
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 (cls.count == 0) {
|
||||
return false;
|
||||
@@ -600,7 +600,7 @@ namespace lbAbiAmd64SysV {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool is_register(LLVMTypeRef type) {
|
||||
gb_internal bool is_register(LLVMTypeRef type) {
|
||||
LLVMTypeKind kind = LLVMGetTypeKind(type);
|
||||
i64 sz = lb_sizeof(type);
|
||||
if (sz == 0) {
|
||||
@@ -617,7 +617,7 @@ namespace lbAbiAmd64SysV {
|
||||
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)) {
|
||||
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)) {
|
||||
LLVMAttributeRef attribute = nullptr;
|
||||
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;
|
||||
LLVMTypeRef i1 = LLVMInt1TypeInContext(c);
|
||||
if (type == i1) {
|
||||
@@ -677,7 +677,7 @@ namespace lbAbiAmd64SysV {
|
||||
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 words = (sz + 7)/8;
|
||||
auto reg_classes = array_make<RegClass>(heap_allocator(), cast(isize)words);
|
||||
@@ -690,7 +690,7 @@ namespace lbAbiAmd64SysV {
|
||||
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];
|
||||
if (oldv == newv) {
|
||||
return;
|
||||
@@ -726,7 +726,7 @@ namespace lbAbiAmd64SysV {
|
||||
(*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 e = cls->count;
|
||||
if (e > 2 && (lb_is_type_kind(t, LLVMStructTypeKind) ||
|
||||
@@ -773,7 +773,7 @@ namespace lbAbiAmd64SysV {
|
||||
}
|
||||
}
|
||||
|
||||
unsigned llvec_len(Array<RegClass> const ®_classes, isize offset) {
|
||||
gb_internal unsigned llvec_len(Array<RegClass> const ®_classes, isize offset) {
|
||||
unsigned len = 1;
|
||||
for (isize i = offset; i < reg_classes.count; i++) {
|
||||
if (reg_classes[i] != RegClass_SSEUp) {
|
||||
@@ -785,7 +785,7 @@ namespace lbAbiAmd64SysV {
|
||||
}
|
||||
|
||||
|
||||
LLVMTypeRef llreg(LLVMContextRef c, Array<RegClass> const ®_classes) {
|
||||
gb_internal LLVMTypeRef llreg(LLVMContextRef c, Array<RegClass> const ®_classes) {
|
||||
auto types = array_make<LLVMTypeRef>(heap_allocator(), 0, reg_classes.count);
|
||||
for (isize i = 0; i < reg_classes.count; /**/) {
|
||||
RegClass reg_class = reg_classes[i];
|
||||
@@ -854,7 +854,7 @@ namespace lbAbiAmd64SysV {
|
||||
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_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) {
|
||||
return lb_arg_type_direct(LLVMVoidTypeInContext(c));
|
||||
} else if (lb_is_type_kind(return_type, LLVMStructTypeKind)) {
|
||||
@@ -980,11 +980,11 @@ namespace lbAbiAmd64SysV {
|
||||
|
||||
|
||||
namespace lbAbiArm64 {
|
||||
Array<lbArgType> compute_arg_types(LLVMContextRef c, LLVMTypeRef *arg_types, unsigned arg_count);
|
||||
LB_ABI_COMPUTE_RETURN_TYPE(compute_return_type);
|
||||
bool is_homogenous_aggregate(LLVMContextRef c, LLVMTypeRef type, LLVMTypeRef *base_type_, unsigned *member_count_);
|
||||
gb_internal Array<lbArgType> compute_arg_types(LLVMContextRef c, LLVMTypeRef *arg_types, unsigned arg_count);
|
||||
gb_internal LB_ABI_COMPUTE_RETURN_TYPE(compute_return_type);
|
||||
gb_internal bool is_homogenous_aggregate(LLVMContextRef c, LLVMTypeRef type, LLVMTypeRef *base_type_, unsigned *member_count_);
|
||||
|
||||
LB_ABI_INFO(abi_info) {
|
||||
gb_internal LB_ABI_INFO(abi_info) {
|
||||
lbFunctionType *ft = gb_alloc_item(permanent_allocator(), lbFunctionType);
|
||||
ft->ctx = c;
|
||||
ft->args = compute_arg_types(c, arg_types, arg_count);
|
||||
@@ -993,7 +993,7 @@ namespace lbAbiArm64 {
|
||||
return ft;
|
||||
}
|
||||
|
||||
bool is_register(LLVMTypeRef type) {
|
||||
gb_internal bool is_register(LLVMTypeRef type) {
|
||||
LLVMTypeKind kind = LLVMGetTypeKind(type);
|
||||
switch (kind) {
|
||||
case LLVMIntegerTypeKind:
|
||||
@@ -1006,7 +1006,7 @@ namespace lbAbiArm64 {
|
||||
return false;
|
||||
}
|
||||
|
||||
lbArgType non_struct(LLVMContextRef c, LLVMTypeRef type) {
|
||||
gb_internal lbArgType non_struct(LLVMContextRef c, LLVMTypeRef type) {
|
||||
LLVMAttributeRef attr = nullptr;
|
||||
LLVMTypeRef i1 = LLVMInt1TypeInContext(c);
|
||||
if (type == i1) {
|
||||
@@ -1015,7 +1015,7 @@ namespace lbAbiArm64 {
|
||||
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));
|
||||
unsigned len = LLVMGetArrayLength(type);
|
||||
if (len == 0) {
|
||||
@@ -1032,7 +1032,7 @@ namespace lbAbiArm64 {
|
||||
}
|
||||
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));
|
||||
unsigned elem_count = LLVMCountStructElementTypes(type);
|
||||
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);
|
||||
switch (kind) {
|
||||
case LLVMFloatTypeKind:
|
||||
@@ -1091,11 +1091,11 @@ namespace lbAbiArm64 {
|
||||
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);
|
||||
}
|
||||
|
||||
LB_ABI_COMPUTE_RETURN_TYPE(compute_return_type) {
|
||||
gb_internal LB_ABI_COMPUTE_RETURN_TYPE(compute_return_type) {
|
||||
LLVMTypeRef homo_base_type = nullptr;
|
||||
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);
|
||||
|
||||
for (unsigned i = 0; i < arg_count; i++) {
|
||||
@@ -1188,12 +1188,12 @@ namespace lbAbiWasm {
|
||||
The approach taken optimizes for passing things in multiple
|
||||
registers/arguments if possible rather than by pointer.
|
||||
*/
|
||||
Array<lbArgType> compute_arg_types(LLVMContextRef c, LLVMTypeRef *arg_types, unsigned arg_count);
|
||||
LB_ABI_COMPUTE_RETURN_TYPE(compute_return_type);
|
||||
gb_internal Array<lbArgType> compute_arg_types(LLVMContextRef c, LLVMTypeRef *arg_types, unsigned arg_count);
|
||||
gb_internal LB_ABI_COMPUTE_RETURN_TYPE(compute_return_type);
|
||||
|
||||
enum {MAX_DIRECT_STRUCT_SIZE = 32};
|
||||
|
||||
LB_ABI_INFO(abi_info) {
|
||||
gb_internal LB_ABI_INFO(abi_info) {
|
||||
lbFunctionType *ft = gb_alloc_item(permanent_allocator(), lbFunctionType);
|
||||
ft->ctx = c;
|
||||
ft->args = compute_arg_types(c, arg_types, arg_count);
|
||||
@@ -1202,7 +1202,7 @@ namespace lbAbiWasm {
|
||||
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)) {
|
||||
LLVMTypeRef cast_type = LLVMVectorType(LLVMInt64TypeInContext(c), 2);
|
||||
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);
|
||||
}
|
||||
|
||||
bool is_basic_register_type(LLVMTypeRef type) {
|
||||
gb_internal bool is_basic_register_type(LLVMTypeRef type) {
|
||||
switch (LLVMGetTypeKind(type)) {
|
||||
case LLVMHalfTypeKind:
|
||||
case LLVMFloatTypeKind:
|
||||
@@ -1233,7 +1233,7 @@ namespace lbAbiWasm {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool type_can_be_direct(LLVMTypeRef type) {
|
||||
gb_internal bool type_can_be_direct(LLVMTypeRef type) {
|
||||
LLVMTypeKind kind = LLVMGetTypeKind(type);
|
||||
i64 sz = lb_sizeof(type);
|
||||
if (sz == 0) {
|
||||
@@ -1259,7 +1259,7 @@ namespace lbAbiWasm {
|
||||
return false;
|
||||
}
|
||||
|
||||
lbArgType is_struct(LLVMContextRef c, LLVMTypeRef type) {
|
||||
gb_internal lbArgType is_struct(LLVMContextRef c, LLVMTypeRef type) {
|
||||
LLVMTypeKind kind = LLVMGetTypeKind(type);
|
||||
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);
|
||||
|
||||
for (unsigned i = 0; i < arg_count; i++) {
|
||||
@@ -1289,7 +1289,7 @@ namespace lbAbiWasm {
|
||||
return args;
|
||||
}
|
||||
|
||||
LB_ABI_COMPUTE_RETURN_TYPE(compute_return_type) {
|
||||
gb_internal LB_ABI_COMPUTE_RETURN_TYPE(compute_return_type) {
|
||||
if (!return_is_defined) {
|
||||
return lb_arg_type_direct(LLVMVoidTypeInContext(c));
|
||||
} else if (lb_is_type_kind(return_type, LLVMStructTypeKind) || lb_is_type_kind(return_type, LLVMArrayTypeKind)) {
|
||||
@@ -1315,10 +1315,10 @@ namespace lbAbiWasm {
|
||||
}
|
||||
|
||||
namespace lbAbiArm32 {
|
||||
Array<lbArgType> compute_arg_types(LLVMContextRef c, LLVMTypeRef *arg_types, unsigned arg_count, ProcCallingConvention calling_convention);
|
||||
lbArgType compute_return_type(LLVMContextRef c, LLVMTypeRef return_type, bool return_is_defined);
|
||||
gb_internal Array<lbArgType> compute_arg_types(LLVMContextRef c, LLVMTypeRef *arg_types, unsigned arg_count, ProcCallingConvention calling_convention);
|
||||
gb_internal lbArgType compute_return_type(LLVMContextRef c, LLVMTypeRef return_type, bool return_is_defined);
|
||||
|
||||
LB_ABI_INFO(abi_info) {
|
||||
gb_internal LB_ABI_INFO(abi_info) {
|
||||
lbFunctionType *ft = gb_alloc_item(permanent_allocator(), lbFunctionType);
|
||||
ft->ctx = c;
|
||||
ft->args = compute_arg_types(c, arg_types, arg_count, calling_convention);
|
||||
@@ -1327,7 +1327,7 @@ namespace lbAbiArm32 {
|
||||
return ft;
|
||||
}
|
||||
|
||||
bool is_register(LLVMTypeRef type, bool is_return) {
|
||||
gb_internal bool is_register(LLVMTypeRef type, bool is_return) {
|
||||
LLVMTypeKind kind = LLVMGetTypeKind(type);
|
||||
switch (kind) {
|
||||
case LLVMHalfTypeKind:
|
||||
@@ -1346,7 +1346,7 @@ namespace lbAbiArm32 {
|
||||
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;
|
||||
LLVMTypeRef i1 = LLVMInt1TypeInContext(c);
|
||||
if (type == i1) {
|
||||
@@ -1355,7 +1355,7 @@ namespace lbAbiArm32 {
|
||||
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);
|
||||
|
||||
for (unsigned i = 0; i < arg_count; i++) {
|
||||
@@ -1380,7 +1380,7 @@ namespace lbAbiArm32 {
|
||||
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) {
|
||||
return lb_arg_type_direct(LLVMVoidTypeInContext(c));
|
||||
} 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) {
|
||||
case ProcCC_None:
|
||||
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(
|
||||
c,
|
||||
arg_types, arg_count,
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#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) {
|
||||
return;
|
||||
}
|
||||
@@ -36,7 +36,7 @@ void lb_add_foreign_library_path(lbModule *m, Entity *e) {
|
||||
mutex_unlock(&m->gen->foreign_mutex);
|
||||
}
|
||||
|
||||
GB_COMPARE_PROC(foreign_library_cmp) {
|
||||
gb_internal GB_COMPARE_PROC(foreign_library_cmp) {
|
||||
int cmp = 0;
|
||||
Entity *x = *(Entity **)a;
|
||||
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);
|
||||
}
|
||||
|
||||
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) {
|
||||
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.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);
|
||||
}
|
||||
|
||||
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);
|
||||
GB_ASSERT(pt->kind == Type_Proc);
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
lbContextData *cd = array_add_and_get(&p->context_stack);
|
||||
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);
|
||||
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};
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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"));
|
||||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
type = base_type(type);
|
||||
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};
|
||||
}
|
||||
|
||||
void lb_debug_print(lbProcedure *p, String const &str) {
|
||||
auto args = array_make<lbValue>(heap_allocator(), 1);
|
||||
args[0] = lb_const_string(p->module, str);
|
||||
lb_emit_runtime_call(p, "print_string", args);
|
||||
}
|
||||
// gb_internal void lb_debug_print(lbProcedure *p, String const &str) {
|
||||
// auto args = array_make<lbValue>(heap_allocator(), 1);
|
||||
// args[0] = lb_const_string(p->module, str);
|
||||
// lb_emit_runtime_call(p, "print_string", args);
|
||||
// }
|
||||
|
||||
lbValue lb_map_set_proc_for_type(lbModule *m, Type *type) {
|
||||
gb_internal lbValue lb_map_set_proc_for_type(lbModule *m, Type *type) {
|
||||
GB_ASSERT(build_context.use_static_map_calls);
|
||||
type = base_type(type);
|
||||
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);
|
||||
if (found) {
|
||||
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);
|
||||
if (found) {
|
||||
return found->addr;
|
||||
@@ -802,7 +802,7 @@ lbValue lb_gen_map_cell_info_ptr(lbModule *m, Type *type) {
|
||||
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
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) {
|
||||
return {};
|
||||
}
|
||||
@@ -880,7 +880,7 @@ lbValue lb_const_hash(lbModule *m, lbValue key, Type *key_type) {
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
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));
|
||||
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));
|
||||
}
|
||||
|
||||
void lb_internal_dynamic_map_set(lbProcedure *p, lbValue const &map_ptr, Type *map_type,
|
||||
lbValue const &map_key, lbValue const &map_value, Ast *node) {
|
||||
gb_internal void lb_internal_dynamic_map_set(lbProcedure *p, lbValue const &map_ptr, Type *map_type,
|
||||
lbValue const &map_key, lbValue const &map_value, Ast *node) {
|
||||
map_type = base_type(map_type);
|
||||
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);
|
||||
|
||||
String proc_name = {};
|
||||
@@ -986,7 +986,7 @@ struct lbGlobalVariable {
|
||||
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) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -1020,7 +1020,7 @@ lbProcedure *lb_create_startup_type_info(lbModule *m) {
|
||||
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) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -1031,7 +1031,7 @@ lbProcedure *lb_create_objc_names(lbModule *main_module) {
|
||||
return p;
|
||||
}
|
||||
|
||||
void lb_finalize_objc_names(lbProcedure *p) {
|
||||
gb_internal void lb_finalize_objc_names(lbProcedure *p) {
|
||||
if (p == nullptr) {
|
||||
return;
|
||||
}
|
||||
@@ -1046,16 +1046,14 @@ void lb_finalize_objc_names(lbProcedure *p) {
|
||||
|
||||
LLVMSetLinkage(p->value, LLVMInternalLinkage);
|
||||
lb_begin_procedure_body(p);
|
||||
for_array(i, m->objc_classes.entries) {
|
||||
auto const &entry = m->objc_classes.entries[i];
|
||||
for (auto const &entry : m->objc_classes) {
|
||||
String name = entry.key.string;
|
||||
args[0] = lb_const_value(m, t_cstring, exact_value_string(name));
|
||||
lbValue ptr = lb_emit_runtime_call(p, "objc_lookUpClass", args);
|
||||
lb_addr_store(p, entry.value, ptr);
|
||||
}
|
||||
|
||||
for_array(i, m->objc_selectors.entries) {
|
||||
auto const &entry = m->objc_selectors.entries[i];
|
||||
for (auto const &entry : m->objc_selectors) {
|
||||
String name = entry.key.string;
|
||||
args[0] = lb_const_value(m, t_cstring, exact_value_string(name));
|
||||
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);
|
||||
lb_populate_function_pass_manager(main_module, default_function_pass_manager, false, build_context.optimization_level);
|
||||
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, "");
|
||||
}
|
||||
|
||||
for_array(i, global_variables) {
|
||||
auto *var = &global_variables[i];
|
||||
if (var->is_initialized) {
|
||||
for (auto &var : global_variables) {
|
||||
if (var.is_initialized) {
|
||||
continue;
|
||||
}
|
||||
|
||||
lbModule *entity_module = main_module;
|
||||
|
||||
Entity *e = var->decl->entity;
|
||||
Entity *e = var.decl->entity;
|
||||
GB_ASSERT(e->kind == Entity_Variable);
|
||||
e->code_gen_module = entity_module;
|
||||
|
||||
Ast *init_expr = var->decl->init_expr;
|
||||
Ast *init_expr = var.decl->init_expr;
|
||||
if (init_expr != nullptr) {
|
||||
lbValue init = lb_build_expr(p, init_expr);
|
||||
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)) {
|
||||
// LLVMSetInitializer(var->var.value, LLVMGetUndef(global_type));
|
||||
LLVMSetInitializer(var->var.value, LLVMConstNull(global_type));
|
||||
var->is_initialized = true;
|
||||
// LLVMSetInitializer(var.var.value, LLVMGetUndef(global_type));
|
||||
LLVMSetInitializer(var.var.value, LLVMConstNull(global_type));
|
||||
var.is_initialized = true;
|
||||
continue;
|
||||
} else if (is_type_untyped_nil(init.type)) {
|
||||
LLVMSetInitializer(var->var.value, LLVMConstNull(global_type));
|
||||
var->is_initialized = true;
|
||||
LLVMSetInitializer(var.var.value, LLVMConstNull(global_type));
|
||||
var.is_initialized = true;
|
||||
continue;
|
||||
}
|
||||
GB_PANIC("Invalid init value, got %s", expr_to_string(init_expr));
|
||||
}
|
||||
|
||||
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)) {
|
||||
if (!var->is_initialized) {
|
||||
if (!var.is_initialized) {
|
||||
if (is_type_proc(init.type)) {
|
||||
init.value = LLVMConstPointerCast(init.value, lb_type(p->module, init.type));
|
||||
}
|
||||
LLVMSetInitializer(var->var.value, init.value);
|
||||
var->is_initialized = true;
|
||||
LLVMSetInitializer(var.var.value, init.value);
|
||||
var.is_initialized = true;
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
var->init = init;
|
||||
var.init = init;
|
||||
}
|
||||
}
|
||||
|
||||
if (var->init.value != nullptr) {
|
||||
GB_ASSERT(!var->is_initialized);
|
||||
Type *t = type_deref(var->var.type);
|
||||
if (var.init.value != nullptr) {
|
||||
GB_ASSERT(!var.is_initialized);
|
||||
Type *t = type_deref(var.var.type);
|
||||
|
||||
if (is_type_any(t)) {
|
||||
// NOTE(bill): Edge case for 'any' type
|
||||
Type *var_type = default_type(var->init.type);
|
||||
lbAddr g = lb_add_global_generated(main_module, var_type, var->init);
|
||||
lb_addr_store(p, g, var->init);
|
||||
Type *var_type = default_type(var.init.type);
|
||||
lbAddr g = lb_add_global_generated(main_module, var_type, var.init);
|
||||
lb_addr_store(p, g, var.init);
|
||||
lbValue gp = lb_addr_get_ptr(p, g);
|
||||
|
||||
lbValue data = lb_emit_struct_ep(p, var->var, 0);
|
||||
lbValue ti = lb_emit_struct_ep(p, var->var, 1);
|
||||
lbValue data = lb_emit_struct_ep(p, var.var, 0);
|
||||
lbValue ti = lb_emit_struct_ep(p, var.var, 1);
|
||||
lb_emit_store(p, data, lb_emit_conv(p, gp, t_rawptr));
|
||||
lb_emit_store(p, ti, lb_type_info(main_module, var_type));
|
||||
} else {
|
||||
LLVMTypeRef vt = llvm_addr_type(p->module, var->var);
|
||||
lbValue src0 = lb_emit_conv(p, var->init, t);
|
||||
LLVMTypeRef vt = llvm_addr_type(p->module, var.var);
|
||||
lbValue src0 = lb_emit_conv(p, var.init, t);
|
||||
LLVMValueRef src = OdinLLVMBuildTransmute(p, src0.value, vt);
|
||||
LLVMValueRef dst = var->var.value;
|
||||
LLVMValueRef dst = var.var.value;
|
||||
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);
|
||||
lb_populate_function_pass_manager(m, default_function_pass_manager, false, build_context.optimization_level);
|
||||
LLVMFinalizeFunctionPassManager(default_function_pass_manager);
|
||||
@@ -1255,8 +1252,8 @@ lbProcedure *lb_create_main_procedure(lbModule *m, lbProcedure *startup_runtime)
|
||||
LLVMValueRef indices[2] = {};
|
||||
indices[0] = LLVMConstInt(lb_type(m, t_i32), 0, false);
|
||||
|
||||
for_array(i, m->info->testing_procedures) {
|
||||
Entity *testing_proc = m->info->testing_procedures[i];
|
||||
isize testing_proc_index = 0;
|
||||
for (Entity *testing_proc : m->info->testing_procedures) {
|
||||
String name = testing_proc->token.string;
|
||||
|
||||
String 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_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] = {};
|
||||
vals[0] = v_pkg.value;
|
||||
@@ -1334,7 +1331,7 @@ lbProcedure *lb_create_main_procedure(lbModule *m, lbProcedure *startup_runtime)
|
||||
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(),
|
||||
build_context.build_paths[BuildPath_Output].basename,
|
||||
STR_LIT("/"),
|
||||
@@ -1350,7 +1347,7 @@ String lb_filepath_ll_for_module(lbModule *m) {
|
||||
|
||||
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(),
|
||||
build_context.build_paths[BuildPath_Output].basename,
|
||||
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 &&
|
||||
LLVMGetFirstGlobal(m->mod) == nullptr) {
|
||||
return true;
|
||||
@@ -1429,7 +1426,7 @@ struct lbLLVMEmitWorker {
|
||||
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);
|
||||
|
||||
char *llvm_error = nullptr;
|
||||
@@ -1444,7 +1441,7 @@ WORKER_TASK_PROC(lb_llvm_emit_worker_proc) {
|
||||
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);
|
||||
|
||||
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);
|
||||
LLVMFinalizeFunctionPassManager(default_function_pass_manager_without_memcpy);
|
||||
|
||||
|
||||
for_array(i, m->procedures_to_generate) {
|
||||
lbProcedure *p = m->procedures_to_generate[i];
|
||||
for (lbProcedure *p : m->procedures_to_generate) {
|
||||
if (p->body != nullptr) { // Build Procedure
|
||||
if (p->flags & lbProcedureFlag_WithoutMemcpyPass) {
|
||||
lb_run_function_pass_manager(default_function_pass_manager_without_memcpy, p);
|
||||
@@ -1505,20 +1500,20 @@ WORKER_TASK_PROC(lb_llvm_function_pass_worker_proc) {
|
||||
}
|
||||
}
|
||||
|
||||
for_array(i, m->equal_procs.entries) {
|
||||
lbProcedure *p = m->equal_procs.entries[i].value;
|
||||
for (auto const &entry : m->equal_procs) {
|
||||
lbProcedure *p = entry.value;
|
||||
lb_run_function_pass_manager(default_function_pass_manager, p);
|
||||
}
|
||||
for_array(i, m->hasher_procs.entries) {
|
||||
lbProcedure *p = m->hasher_procs.entries[i].value;
|
||||
for (auto const &entry : m->hasher_procs) {
|
||||
lbProcedure *p = entry.value;
|
||||
lb_run_function_pass_manager(default_function_pass_manager, p);
|
||||
}
|
||||
for_array(i, m->map_get_procs.entries) {
|
||||
lbProcedure *p = m->map_get_procs.entries[i].value;
|
||||
for (auto const &entry : m->map_get_procs) {
|
||||
lbProcedure *p = entry.value;
|
||||
lb_run_function_pass_manager(default_function_pass_manager, p);
|
||||
}
|
||||
for_array(i, m->map_set_procs.entries) {
|
||||
lbProcedure *p = m->map_set_procs.entries[i].value;
|
||||
for (auto const &entry : m->map_set_procs) {
|
||||
lbProcedure *p = entry.value;
|
||||
lb_run_function_pass_manager(default_function_pass_manager, p);
|
||||
}
|
||||
|
||||
@@ -1531,7 +1526,7 @@ struct lbLLVMModulePassWorkerData {
|
||||
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;
|
||||
LLVMPassManagerRef module_pass_manager = LLVMCreatePassManager();
|
||||
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) {
|
||||
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");
|
||||
|
||||
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);
|
||||
for_array(i, gen->modules.entries) {
|
||||
LLVMSetTarget(gen->modules.entries[i].value->mod, target_triple);
|
||||
for (auto const &entry : gen->modules) {
|
||||
LLVMSetTarget(entry.value->mod, target_triple);
|
||||
}
|
||||
|
||||
LLVMTargetRef target = {};
|
||||
@@ -1701,7 +1696,7 @@ void lb_generate_code(lbGenerator *gen) {
|
||||
|
||||
// NOTE(bill): Target Machine Creation
|
||||
// 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.
|
||||
LLVMRelocMode reloc_mode = LLVMRelocDefault;
|
||||
@@ -1727,27 +1722,27 @@ void lb_generate_code(lbGenerator *gen) {
|
||||
break;
|
||||
}
|
||||
|
||||
for_array(i, gen->modules.entries) {
|
||||
target_machines[i] = LLVMCreateTargetMachine(
|
||||
for (auto const &entry : gen->modules) {
|
||||
LLVMTargetMachineRef target_machine = LLVMCreateTargetMachine(
|
||||
target, target_triple, llvm_cpu,
|
||||
llvm_features,
|
||||
code_gen_level,
|
||||
reloc_mode,
|
||||
code_mode);
|
||||
LLVMSetModuleDataLayout(gen->modules.entries[i].value->mod, LLVMCreateTargetDataLayout(target_machines[i]));
|
||||
lbModule *m = entry.value;
|
||||
m->target_machine = target_machine;
|
||||
LLVMSetModuleDataLayout(m->mod, LLVMCreateTargetDataLayout(target_machine));
|
||||
array_add(&target_machines, target_machine);
|
||||
}
|
||||
|
||||
for_array(i, gen->modules.entries) {
|
||||
lbModule *m = gen->modules.entries[i].value;
|
||||
for (auto const &entry : gen->modules) {
|
||||
lbModule *m = entry.value;
|
||||
if (m->debug_builder) { // Debug Info
|
||||
for_array(i, info->files.entries) {
|
||||
AstFile *f = info->files.entries[i].value;
|
||||
String fullpath = f->fullpath;
|
||||
String filename = remove_directory_from_path(fullpath);
|
||||
String directory = directory_from_path(fullpath);
|
||||
for (auto const &file_entry : info->files) {
|
||||
AstFile *f = file_entry.value;
|
||||
LLVMMetadataRef res = LLVMDIBuilderCreateFile(m->debug_builder,
|
||||
cast(char const *)filename.text, filename.len,
|
||||
cast(char const *)directory.text, directory.len);
|
||||
cast(char const *)f->filename.text, f->filename.len,
|
||||
cast(char const *)f->directory.text, f->directory.len);
|
||||
lb_set_llvm_metadata(m, f, res);
|
||||
}
|
||||
|
||||
@@ -1817,9 +1812,7 @@ void lb_generate_code(lbGenerator *gen) {
|
||||
// NOTE(bill): Removes need for heap allocation by making it global memory
|
||||
isize count = 0;
|
||||
|
||||
for_array(entry_index, m->info->type_info_types) {
|
||||
Type *t = m->info->type_info_types[entry_index];
|
||||
|
||||
for (Type *t : m->info->type_info_types) {
|
||||
isize index = lb_type_info_index(m->info, t, false);
|
||||
if (index < 0) {
|
||||
continue;
|
||||
@@ -1890,8 +1883,7 @@ void lb_generate_code(lbGenerator *gen) {
|
||||
isize global_variable_max_count = 0;
|
||||
bool already_has_entry_point = false;
|
||||
|
||||
for_array(i, info->entities) {
|
||||
Entity *e = info->entities[i];
|
||||
for (Entity *e : info->entities) {
|
||||
String name = e->token.string;
|
||||
|
||||
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);
|
||||
|
||||
for_array(i, info->variable_init_order) {
|
||||
DeclInfo *d = info->variable_init_order[i];
|
||||
|
||||
for (DeclInfo *d : info->variable_init_order) {
|
||||
Entity *e = d->entity;
|
||||
|
||||
if ((e->scope->flags & ScopeFlag_File) == 0) {
|
||||
@@ -2060,15 +2050,14 @@ void lb_generate_code(lbGenerator *gen) {
|
||||
gb_unused(startup_runtime);
|
||||
|
||||
if (build_context.ODIN_DEBUG) {
|
||||
for_array(i, builtin_pkg->scope->elements.entries) {
|
||||
Entity *e = builtin_pkg->scope->elements.entries[i].value;
|
||||
for (auto const &entry : builtin_pkg->scope->elements) {
|
||||
Entity *e = entry.value;
|
||||
add_debug_info_for_global_constant_from_entity(gen, e);
|
||||
}
|
||||
}
|
||||
|
||||
TIME_SECTION("LLVM Global Procedures and Types");
|
||||
for_array(i, info->entities) {
|
||||
Entity *e = info->entities[i];
|
||||
for (Entity *e : info->entities) {
|
||||
String name = e->token.string;
|
||||
Scope * scope = e->scope;
|
||||
|
||||
@@ -2130,9 +2119,10 @@ void lb_generate_code(lbGenerator *gen) {
|
||||
}
|
||||
|
||||
TIME_SECTION("LLVM Procedure Generation");
|
||||
for_array(j, gen->modules.entries) {
|
||||
lbModule *m = gen->modules.entries[j].value;
|
||||
for_array(i, m->procedures_to_generate) {
|
||||
for (auto const &entry : gen->modules) {
|
||||
lbModule *m = entry.value;
|
||||
// NOTE(bill): procedures may be added during generation
|
||||
for (isize i = 0; i < m->procedures_to_generate.count; i++) {
|
||||
lbProcedure *p = m->procedures_to_generate[i];
|
||||
lb_generate_procedure(m, p);
|
||||
}
|
||||
@@ -2143,9 +2133,10 @@ void lb_generate_code(lbGenerator *gen) {
|
||||
lb_create_main_procedure(default_module, startup_runtime);
|
||||
}
|
||||
|
||||
for_array(j, gen->modules.entries) {
|
||||
lbModule *m = gen->modules.entries[j].value;
|
||||
for_array(i, m->missing_procedures_to_check) {
|
||||
for (auto const &entry : gen->modules) {
|
||||
lbModule *m = entry.value;
|
||||
// NOTE(bill): procedures may be added during generation
|
||||
for (isize i = 0; i < m->missing_procedures_to_check.count; i++) {
|
||||
lbProcedure *p = m->missing_procedures_to_check[i];
|
||||
debugf("Generate missing procedure: %.*s\n", LIT(p->name));
|
||||
lb_generate_procedure(m, p);
|
||||
@@ -2155,24 +2146,9 @@ void lb_generate_code(lbGenerator *gen) {
|
||||
lb_finalize_objc_names(objc_names);
|
||||
|
||||
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");
|
||||
for_array(j, gen->modules.entries) {
|
||||
lbModule *m = gen->modules.entries[j].value;
|
||||
for (auto const &entry : gen->modules) {
|
||||
lbModule *m = entry.value;
|
||||
if (m->debug_builder != nullptr) {
|
||||
lb_debug_complete_types(m);
|
||||
LLVMDIBuilderFinalize(m->debug_builder);
|
||||
@@ -2183,23 +2159,21 @@ void lb_generate_code(lbGenerator *gen) {
|
||||
|
||||
|
||||
TIME_SECTION("LLVM Function Pass");
|
||||
for_array(i, gen->modules.entries) {
|
||||
lbModule *m = gen->modules.entries[i].value;
|
||||
|
||||
for (auto const &entry : gen->modules) {
|
||||
lbModule *m = entry.value;
|
||||
lb_llvm_function_pass_worker_proc(m);
|
||||
}
|
||||
|
||||
TIME_SECTION("LLVM Module Pass");
|
||||
|
||||
for_array(i, gen->modules.entries) {
|
||||
lbModule *m = gen->modules.entries[i].value;
|
||||
|
||||
for (auto const &entry : gen->modules) {
|
||||
lbModule *m = entry.value;
|
||||
lb_run_remove_unused_function_pass(m);
|
||||
lb_run_remove_unused_globals_pass(m);
|
||||
|
||||
auto wd = gb_alloc_item(permanent_allocator(), lbLLVMModulePassWorkerData);
|
||||
wd->m = m;
|
||||
wd->target_machine = target_machines[i];
|
||||
wd->target_machine = m->target_machine;
|
||||
|
||||
lb_llvm_module_pass_worker_proc(wd);
|
||||
}
|
||||
@@ -2214,8 +2188,8 @@ void lb_generate_code(lbGenerator *gen) {
|
||||
}
|
||||
|
||||
|
||||
for_array(j, gen->modules.entries) {
|
||||
lbModule *m = gen->modules.entries[j].value;
|
||||
for (auto const &entry : gen->modules) {
|
||||
lbModule *m = entry.value;
|
||||
if (LLVMVerifyModule(m->mod, LLVMReturnStatusAction, &llvm_error)) {
|
||||
gb_printf_err("LLVM Error:\n%s\n", llvm_error);
|
||||
if (build_context.keep_temp_files) {
|
||||
@@ -2236,9 +2210,8 @@ void lb_generate_code(lbGenerator *gen) {
|
||||
build_context.build_mode == BuildMode_LLVM_IR) {
|
||||
TIME_SECTION("LLVM Print Module to File");
|
||||
|
||||
for_array(j, gen->modules.entries) {
|
||||
lbModule *m = gen->modules.entries[j].value;
|
||||
|
||||
for (auto const &entry : gen->modules) {
|
||||
lbModule *m = entry.value;
|
||||
if (lb_is_module_empty(m)) {
|
||||
continue;
|
||||
}
|
||||
@@ -2260,8 +2233,8 @@ void lb_generate_code(lbGenerator *gen) {
|
||||
|
||||
TIME_SECTION("LLVM Add Foreign Library Paths");
|
||||
|
||||
for_array(j, gen->modules.entries) {
|
||||
lbModule *m = gen->modules.entries[j].value;
|
||||
for (auto const &entry : gen->modules) {
|
||||
lbModule *m = entry.value;
|
||||
for_array(i, m->info->required_foreign_imports_through_force) {
|
||||
Entity *e = m->info->required_foreign_imports_through_force[i];
|
||||
lb_add_foreign_library_path(m, e);
|
||||
@@ -2275,16 +2248,16 @@ void lb_generate_code(lbGenerator *gen) {
|
||||
TIME_SECTION("LLVM Object Generation");
|
||||
|
||||
isize non_empty_module_count = 0;
|
||||
for_array(j, gen->modules.entries) {
|
||||
lbModule *m = gen->modules.entries[j].value;
|
||||
for (auto const &entry : gen->modules) {
|
||||
lbModule *m = entry.value;
|
||||
if (!lb_is_module_empty(m)) {
|
||||
non_empty_module_count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (do_threading && non_empty_module_count > 1) {
|
||||
for_array(j, gen->modules.entries) {
|
||||
lbModule *m = gen->modules.entries[j].value;
|
||||
for (auto const &entry : gen->modules) {
|
||||
lbModule *m = entry.value;
|
||||
if (lb_is_module_empty(m)) {
|
||||
continue;
|
||||
}
|
||||
@@ -2295,7 +2268,7 @@ void lb_generate_code(lbGenerator *gen) {
|
||||
array_add(&gen->output_temp_paths, filepath_ll);
|
||||
|
||||
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->filepath_obj = filepath_obj;
|
||||
wd->m = m;
|
||||
@@ -2304,8 +2277,8 @@ void lb_generate_code(lbGenerator *gen) {
|
||||
|
||||
thread_pool_wait(&global_thread_pool);
|
||||
} else {
|
||||
for_array(j, gen->modules.entries) {
|
||||
lbModule *m = gen->modules.entries[j].value;
|
||||
for (auto const &entry : gen->modules) {
|
||||
lbModule *m = entry.value;
|
||||
if (lb_is_module_empty(m)) {
|
||||
continue;
|
||||
}
|
||||
@@ -2319,7 +2292,7 @@ void lb_generate_code(lbGenerator *gen) {
|
||||
|
||||
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_exit(1);
|
||||
return;
|
||||
|
||||
@@ -122,6 +122,7 @@ struct lbModule {
|
||||
LLVMContextRef ctx;
|
||||
|
||||
struct lbGenerator *gen;
|
||||
LLVMTargetMachineRef target_machine;
|
||||
|
||||
CheckerInfo *info;
|
||||
AstPackage *pkg; // associated
|
||||
@@ -321,197 +322,197 @@ struct lbProcedure {
|
||||
#define LLVMBuildPtrDiff2(Builder__, Ty__, LHS__, RHS__, Name__) LLVMBuildPtrDiff(Builder__, LHS__, RHS__, Name__)
|
||||
#endif
|
||||
|
||||
bool lb_init_generator(lbGenerator *gen, Checker *c);
|
||||
gb_internal bool lb_init_generator(lbGenerator *gen, Checker *c);
|
||||
|
||||
String lb_mangle_name(lbModule *m, Entity *e);
|
||||
String lb_get_entity_name(lbModule *m, Entity *e, String name = {});
|
||||
gb_internal String lb_mangle_name(lbModule *m, Entity *e);
|
||||
gb_internal String lb_get_entity_name(lbModule *m, Entity *e, String name = {});
|
||||
|
||||
LLVMAttributeRef lb_create_enum_attribute(LLVMContextRef ctx, char const *name, u64 value=0);
|
||||
LLVMAttributeRef lb_create_enum_attribute_with_type(LLVMContextRef ctx, char const *name, LLVMTypeRef type);
|
||||
void lb_add_proc_attribute_at_index(lbProcedure *p, isize index, char const *name, u64 value);
|
||||
void lb_add_proc_attribute_at_index(lbProcedure *p, isize index, char const *name);
|
||||
lbProcedure *lb_create_procedure(lbModule *module, Entity *entity, bool ignore_body=false);
|
||||
void lb_end_procedure(lbProcedure *p);
|
||||
gb_internal LLVMAttributeRef lb_create_enum_attribute(LLVMContextRef ctx, char const *name, u64 value=0);
|
||||
gb_internal LLVMAttributeRef lb_create_enum_attribute_with_type(LLVMContextRef ctx, char const *name, LLVMTypeRef type);
|
||||
gb_internal void lb_add_proc_attribute_at_index(lbProcedure *p, isize index, char const *name, u64 value);
|
||||
gb_internal void lb_add_proc_attribute_at_index(lbProcedure *p, isize index, char const *name);
|
||||
gb_internal lbProcedure *lb_create_procedure(lbModule *module, Entity *entity, bool ignore_body=false);
|
||||
gb_internal void lb_end_procedure(lbProcedure *p);
|
||||
|
||||
|
||||
LLVMTypeRef lb_type(lbModule *m, Type *type);
|
||||
LLVMTypeRef llvm_get_element_type(LLVMTypeRef type);
|
||||
gb_internal LLVMTypeRef lb_type(lbModule *m, Type *type);
|
||||
gb_internal LLVMTypeRef llvm_get_element_type(LLVMTypeRef type);
|
||||
|
||||
lbBlock *lb_create_block(lbProcedure *p, char const *name, bool append=false);
|
||||
gb_internal lbBlock *lb_create_block(lbProcedure *p, char const *name, bool append=false);
|
||||
|
||||
lbValue lb_const_nil(lbModule *m, Type *type);
|
||||
lbValue lb_const_undef(lbModule *m, Type *type);
|
||||
lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_local=true);
|
||||
lbValue lb_const_bool(lbModule *m, Type *type, bool value);
|
||||
lbValue lb_const_int(lbModule *m, Type *type, u64 value);
|
||||
gb_internal lbValue lb_const_nil(lbModule *m, Type *type);
|
||||
gb_internal lbValue lb_const_undef(lbModule *m, Type *type);
|
||||
gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_local=true);
|
||||
gb_internal lbValue lb_const_bool(lbModule *m, Type *type, bool value);
|
||||
gb_internal lbValue lb_const_int(lbModule *m, Type *type, u64 value);
|
||||
|
||||
|
||||
lbAddr lb_addr(lbValue addr);
|
||||
Type *lb_addr_type(lbAddr const &addr);
|
||||
LLVMTypeRef llvm_addr_type(lbModule *module, lbValue addr_val);
|
||||
void lb_addr_store(lbProcedure *p, lbAddr addr, lbValue value);
|
||||
lbValue lb_addr_load(lbProcedure *p, lbAddr const &addr);
|
||||
lbValue lb_emit_load(lbProcedure *p, lbValue v);
|
||||
void lb_emit_store(lbProcedure *p, lbValue ptr, lbValue value);
|
||||
gb_internal lbAddr lb_addr(lbValue addr);
|
||||
gb_internal Type *lb_addr_type(lbAddr const &addr);
|
||||
gb_internal LLVMTypeRef llvm_addr_type(lbModule *module, lbValue addr_val);
|
||||
gb_internal void lb_addr_store(lbProcedure *p, lbAddr addr, lbValue value);
|
||||
gb_internal lbValue lb_addr_load(lbProcedure *p, lbAddr const &addr);
|
||||
gb_internal lbValue lb_emit_load(lbProcedure *p, lbValue v);
|
||||
gb_internal void lb_emit_store(lbProcedure *p, lbValue ptr, lbValue value);
|
||||
|
||||
|
||||
void lb_build_stmt(lbProcedure *p, Ast *stmt);
|
||||
lbValue lb_build_expr(lbProcedure *p, Ast *expr);
|
||||
lbAddr lb_build_addr(lbProcedure *p, Ast *expr);
|
||||
void lb_build_stmt_list(lbProcedure *p, Array<Ast *> const &stmts);
|
||||
gb_internal void lb_build_stmt(lbProcedure *p, Ast *stmt);
|
||||
gb_internal lbValue lb_build_expr(lbProcedure *p, Ast *expr);
|
||||
gb_internal lbAddr lb_build_addr(lbProcedure *p, Ast *expr);
|
||||
gb_internal void lb_build_stmt_list(lbProcedure *p, Array<Ast *> const &stmts);
|
||||
|
||||
lbValue lb_emit_epi(lbProcedure *p, lbValue const &value, isize index);
|
||||
lbValue lb_emit_epi(lbModule *m, lbValue const &value, isize index);
|
||||
lbValue lb_emit_array_epi(lbModule *m, lbValue s, isize index);
|
||||
lbValue lb_emit_struct_ep(lbProcedure *p, lbValue s, i32 index);
|
||||
lbValue lb_emit_struct_ev(lbProcedure *p, lbValue s, i32 index);
|
||||
lbValue lb_emit_tuple_ev(lbProcedure *p, lbValue value, i32 index);
|
||||
lbValue lb_emit_array_epi(lbProcedure *p, lbValue value, isize index);
|
||||
lbValue lb_emit_array_ep(lbProcedure *p, lbValue s, lbValue index);
|
||||
lbValue lb_emit_deep_field_gep(lbProcedure *p, lbValue e, Selection sel);
|
||||
lbValue lb_emit_deep_field_ev(lbProcedure *p, lbValue e, Selection sel);
|
||||
gb_internal lbValue lb_emit_epi(lbProcedure *p, lbValue const &value, isize index);
|
||||
gb_internal lbValue lb_emit_epi(lbModule *m, lbValue const &value, isize index);
|
||||
gb_internal lbValue lb_emit_array_epi(lbModule *m, lbValue s, isize index);
|
||||
gb_internal lbValue lb_emit_struct_ep(lbProcedure *p, lbValue s, i32 index);
|
||||
gb_internal lbValue lb_emit_struct_ev(lbProcedure *p, lbValue s, i32 index);
|
||||
gb_internal lbValue lb_emit_tuple_ev(lbProcedure *p, lbValue value, i32 index);
|
||||
gb_internal lbValue lb_emit_array_epi(lbProcedure *p, lbValue value, isize index);
|
||||
gb_internal lbValue lb_emit_array_ep(lbProcedure *p, lbValue s, lbValue index);
|
||||
gb_internal lbValue lb_emit_deep_field_gep(lbProcedure *p, lbValue e, Selection sel);
|
||||
gb_internal lbValue lb_emit_deep_field_ev(lbProcedure *p, lbValue e, Selection sel);
|
||||
|
||||
lbValue lb_emit_matrix_ep(lbProcedure *p, lbValue s, lbValue row, lbValue column);
|
||||
lbValue lb_emit_matrix_epi(lbProcedure *p, lbValue s, isize row, isize column);
|
||||
lbValue lb_emit_matrix_ev(lbProcedure *p, lbValue s, isize row, isize column);
|
||||
gb_internal lbValue lb_emit_matrix_ep(lbProcedure *p, lbValue s, lbValue row, lbValue column);
|
||||
gb_internal lbValue lb_emit_matrix_epi(lbProcedure *p, lbValue s, isize row, isize column);
|
||||
gb_internal lbValue lb_emit_matrix_ev(lbProcedure *p, lbValue s, isize row, isize column);
|
||||
|
||||
|
||||
lbValue lb_emit_arith(lbProcedure *p, TokenKind op, lbValue lhs, lbValue rhs, Type *type);
|
||||
lbValue lb_emit_byte_swap(lbProcedure *p, lbValue value, Type *end_type);
|
||||
void lb_emit_defer_stmts(lbProcedure *p, lbDeferExitKind kind, lbBlock *block);
|
||||
lbValue lb_emit_transmute(lbProcedure *p, lbValue value, Type *t);
|
||||
lbValue lb_emit_comp(lbProcedure *p, TokenKind op_kind, lbValue left, lbValue right);
|
||||
lbValue lb_emit_call(lbProcedure *p, lbValue value, Array<lbValue> const &args, ProcInlining inlining = ProcInlining_none);
|
||||
lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t);
|
||||
lbValue lb_emit_comp_against_nil(lbProcedure *p, TokenKind op_kind, lbValue x);
|
||||
gb_internal lbValue lb_emit_arith(lbProcedure *p, TokenKind op, lbValue lhs, lbValue rhs, Type *type);
|
||||
gb_internal lbValue lb_emit_byte_swap(lbProcedure *p, lbValue value, Type *end_type);
|
||||
gb_internal void lb_emit_defer_stmts(lbProcedure *p, lbDeferExitKind kind, lbBlock *block);
|
||||
gb_internal lbValue lb_emit_transmute(lbProcedure *p, lbValue value, Type *t);
|
||||
gb_internal lbValue lb_emit_comp(lbProcedure *p, TokenKind op_kind, lbValue left, lbValue right);
|
||||
gb_internal lbValue lb_emit_call(lbProcedure *p, lbValue value, Array<lbValue> const &args, ProcInlining inlining = ProcInlining_none);
|
||||
gb_internal lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t);
|
||||
gb_internal lbValue lb_emit_comp_against_nil(lbProcedure *p, TokenKind op_kind, lbValue x);
|
||||
|
||||
void lb_emit_jump(lbProcedure *p, lbBlock *target_block);
|
||||
void lb_emit_if(lbProcedure *p, lbValue cond, lbBlock *true_block, lbBlock *false_block);
|
||||
void lb_start_block(lbProcedure *p, lbBlock *b);
|
||||
gb_internal void lb_emit_jump(lbProcedure *p, lbBlock *target_block);
|
||||
gb_internal void lb_emit_if(lbProcedure *p, lbValue cond, lbBlock *true_block, lbBlock *false_block);
|
||||
gb_internal void lb_start_block(lbProcedure *p, lbBlock *b);
|
||||
|
||||
lbValue lb_build_call_expr(lbProcedure *p, Ast *expr);
|
||||
gb_internal lbValue lb_build_call_expr(lbProcedure *p, Ast *expr);
|
||||
|
||||
|
||||
lbAddr lb_find_or_generate_context_ptr(lbProcedure *p);
|
||||
lbContextData *lb_push_context_onto_stack(lbProcedure *p, lbAddr ctx);
|
||||
lbContextData *lb_push_context_onto_stack_from_implicit_parameter(lbProcedure *p);
|
||||
gb_internal lbAddr lb_find_or_generate_context_ptr(lbProcedure *p);
|
||||
gb_internal lbContextData *lb_push_context_onto_stack(lbProcedure *p, lbAddr ctx);
|
||||
gb_internal lbContextData *lb_push_context_onto_stack_from_implicit_parameter(lbProcedure *p);
|
||||
|
||||
|
||||
lbAddr lb_add_global_generated(lbModule *m, Type *type, lbValue value={}, Entity **entity_=nullptr);
|
||||
lbAddr lb_add_local(lbProcedure *p, Type *type, Entity *e=nullptr, bool zero_init=true, bool force_no_init=false);
|
||||
gb_internal lbAddr lb_add_global_generated(lbModule *m, Type *type, lbValue value={}, Entity **entity_=nullptr);
|
||||
gb_internal lbAddr lb_add_local(lbProcedure *p, Type *type, Entity *e=nullptr, bool zero_init=true, bool force_no_init=false);
|
||||
|
||||
void lb_add_foreign_library_path(lbModule *m, Entity *e);
|
||||
gb_internal void lb_add_foreign_library_path(lbModule *m, Entity *e);
|
||||
|
||||
lbValue lb_typeid(lbModule *m, Type *type);
|
||||
gb_internal lbValue lb_typeid(lbModule *m, Type *type);
|
||||
|
||||
lbValue lb_address_from_load_or_generate_local(lbProcedure *p, lbValue value);
|
||||
lbValue lb_address_from_load(lbProcedure *p, lbValue value);
|
||||
void lb_add_defer_node(lbProcedure *p, isize scope_index, Ast *stmt);
|
||||
lbAddr lb_add_local_generated(lbProcedure *p, Type *type, bool zero_init);
|
||||
gb_internal lbValue lb_address_from_load_or_generate_local(lbProcedure *p, lbValue value);
|
||||
gb_internal lbValue lb_address_from_load(lbProcedure *p, lbValue value);
|
||||
gb_internal void lb_add_defer_node(lbProcedure *p, isize scope_index, Ast *stmt);
|
||||
gb_internal lbAddr lb_add_local_generated(lbProcedure *p, Type *type, bool zero_init);
|
||||
|
||||
lbValue lb_emit_runtime_call(lbProcedure *p, char const *c_name, Array<lbValue> const &args);
|
||||
gb_internal lbValue lb_emit_runtime_call(lbProcedure *p, char const *c_name, Array<lbValue> const &args);
|
||||
|
||||
|
||||
lbValue lb_emit_ptr_offset(lbProcedure *p, lbValue ptr, lbValue index);
|
||||
lbValue lb_string_elem(lbProcedure *p, lbValue string);
|
||||
lbValue lb_string_len(lbProcedure *p, lbValue string);
|
||||
lbValue lb_cstring_len(lbProcedure *p, lbValue value);
|
||||
lbValue lb_array_elem(lbProcedure *p, lbValue array_ptr);
|
||||
lbValue lb_slice_elem(lbProcedure *p, lbValue slice);
|
||||
lbValue lb_slice_len(lbProcedure *p, lbValue slice);
|
||||
lbValue lb_dynamic_array_elem(lbProcedure *p, lbValue da);
|
||||
lbValue lb_dynamic_array_len(lbProcedure *p, lbValue da);
|
||||
lbValue lb_dynamic_array_cap(lbProcedure *p, lbValue da);
|
||||
lbValue lb_dynamic_array_allocator(lbProcedure *p, lbValue da);
|
||||
lbValue lb_map_len(lbProcedure *p, lbValue value);
|
||||
lbValue lb_map_cap(lbProcedure *p, lbValue value);
|
||||
lbValue lb_soa_struct_len(lbProcedure *p, lbValue value);
|
||||
void lb_emit_increment(lbProcedure *p, lbValue addr);
|
||||
lbValue lb_emit_select(lbProcedure *p, lbValue cond, lbValue x, lbValue y);
|
||||
gb_internal lbValue lb_emit_ptr_offset(lbProcedure *p, lbValue ptr, lbValue index);
|
||||
gb_internal lbValue lb_string_elem(lbProcedure *p, lbValue string);
|
||||
gb_internal lbValue lb_string_len(lbProcedure *p, lbValue string);
|
||||
gb_internal lbValue lb_cstring_len(lbProcedure *p, lbValue value);
|
||||
gb_internal lbValue lb_array_elem(lbProcedure *p, lbValue array_ptr);
|
||||
gb_internal lbValue lb_slice_elem(lbProcedure *p, lbValue slice);
|
||||
gb_internal lbValue lb_slice_len(lbProcedure *p, lbValue slice);
|
||||
gb_internal lbValue lb_dynamic_array_elem(lbProcedure *p, lbValue da);
|
||||
gb_internal lbValue lb_dynamic_array_len(lbProcedure *p, lbValue da);
|
||||
gb_internal lbValue lb_dynamic_array_cap(lbProcedure *p, lbValue da);
|
||||
gb_internal lbValue lb_dynamic_array_allocator(lbProcedure *p, lbValue da);
|
||||
gb_internal lbValue lb_map_len(lbProcedure *p, lbValue value);
|
||||
gb_internal lbValue lb_map_cap(lbProcedure *p, lbValue value);
|
||||
gb_internal lbValue lb_soa_struct_len(lbProcedure *p, lbValue value);
|
||||
gb_internal void lb_emit_increment(lbProcedure *p, lbValue addr);
|
||||
gb_internal lbValue lb_emit_select(lbProcedure *p, lbValue cond, lbValue x, lbValue y);
|
||||
|
||||
lbValue lb_emit_mul_add(lbProcedure *p, lbValue a, lbValue b, lbValue c, Type *t);
|
||||
gb_internal lbValue lb_emit_mul_add(lbProcedure *p, lbValue a, lbValue b, lbValue c, Type *t);
|
||||
|
||||
void lb_fill_slice(lbProcedure *p, lbAddr const &slice, lbValue base_elem, lbValue len);
|
||||
gb_internal void lb_fill_slice(lbProcedure *p, lbAddr const &slice, lbValue base_elem, lbValue len);
|
||||
|
||||
lbValue lb_type_info(lbModule *m, Type *type);
|
||||
gb_internal lbValue lb_type_info(lbModule *m, Type *type);
|
||||
|
||||
lbValue lb_find_or_add_entity_string(lbModule *m, String const &str);
|
||||
lbValue lb_generate_anonymous_proc_lit(lbModule *m, String const &prefix_name, Ast *expr, lbProcedure *parent = nullptr);
|
||||
gb_internal lbValue lb_find_or_add_entity_string(lbModule *m, String const &str);
|
||||
gb_internal lbValue lb_generate_anonymous_proc_lit(lbModule *m, String const &prefix_name, Ast *expr, lbProcedure *parent = nullptr);
|
||||
|
||||
bool lb_is_const(lbValue value);
|
||||
bool lb_is_const_or_global(lbValue value);
|
||||
bool lb_is_const_nil(lbValue value);
|
||||
String lb_get_const_string(lbModule *m, lbValue value);
|
||||
gb_internal bool lb_is_const(lbValue value);
|
||||
gb_internal bool lb_is_const_or_global(lbValue value);
|
||||
gb_internal bool lb_is_const_nil(lbValue value);
|
||||
gb_internal String lb_get_const_string(lbModule *m, lbValue value);
|
||||
|
||||
lbValue lb_generate_local_array(lbProcedure *p, Type *elem_type, i64 count, bool zero_init=true);
|
||||
lbValue lb_generate_global_array(lbModule *m, Type *elem_type, i64 count, String prefix, i64 id);
|
||||
lbValue lb_gen_map_key_hash(lbProcedure *p, lbValue key, Type *key_type, lbValue *key_ptr_);
|
||||
lbValue lb_gen_map_cell_info_ptr(lbModule *m, Type *type);
|
||||
lbValue lb_gen_map_info_ptr(lbModule *m, Type *map_type);
|
||||
gb_internal lbValue lb_generate_local_array(lbProcedure *p, Type *elem_type, i64 count, bool zero_init=true);
|
||||
gb_internal lbValue lb_generate_global_array(lbModule *m, Type *elem_type, i64 count, String prefix, i64 id);
|
||||
gb_internal lbValue lb_gen_map_key_hash(lbProcedure *p, lbValue key, Type *key_type, lbValue *key_ptr_);
|
||||
gb_internal lbValue lb_gen_map_cell_info_ptr(lbModule *m, Type *type);
|
||||
gb_internal lbValue lb_gen_map_info_ptr(lbModule *m, Type *map_type);
|
||||
|
||||
lbValue lb_internal_dynamic_map_get_ptr(lbProcedure *p, lbValue const &map_ptr, lbValue const &key);
|
||||
void lb_internal_dynamic_map_set(lbProcedure *p, lbValue const &map_ptr, Type *map_type, lbValue const &map_key, lbValue const &map_value, Ast *node);
|
||||
lbValue lb_dynamic_map_reserve(lbProcedure *p, lbValue const &map_ptr, isize const capacity, TokenPos const &pos);
|
||||
gb_internal lbValue lb_internal_dynamic_map_get_ptr(lbProcedure *p, lbValue const &map_ptr, lbValue const &key);
|
||||
gb_internal void lb_internal_dynamic_map_set(lbProcedure *p, lbValue const &map_ptr, Type *map_type, lbValue const &map_key, lbValue const &map_value, Ast *node);
|
||||
gb_internal lbValue lb_dynamic_map_reserve(lbProcedure *p, lbValue const &map_ptr, isize const capacity, TokenPos const &pos);
|
||||
|
||||
lbValue lb_find_procedure_value_from_entity(lbModule *m, Entity *e);
|
||||
lbValue lb_find_value_from_entity(lbModule *m, Entity *e);
|
||||
gb_internal lbValue lb_find_procedure_value_from_entity(lbModule *m, Entity *e);
|
||||
gb_internal lbValue lb_find_value_from_entity(lbModule *m, Entity *e);
|
||||
|
||||
void lb_store_type_case_implicit(lbProcedure *p, Ast *clause, lbValue value);
|
||||
lbAddr lb_store_range_stmt_val(lbProcedure *p, Ast *stmt_val, lbValue value);
|
||||
lbValue lb_emit_source_code_location_const(lbProcedure *p, String const &procedure, TokenPos const &pos);
|
||||
gb_internal void lb_store_type_case_implicit(lbProcedure *p, Ast *clause, lbValue value);
|
||||
gb_internal lbAddr lb_store_range_stmt_val(lbProcedure *p, Ast *stmt_val, lbValue value);
|
||||
gb_internal lbValue lb_emit_source_code_location_const(lbProcedure *p, String const &procedure, TokenPos const &pos);
|
||||
|
||||
lbValue lb_handle_param_value(lbProcedure *p, Type *parameter_type, ParameterValue const ¶m_value, TokenPos const &pos);
|
||||
gb_internal lbValue lb_handle_param_value(lbProcedure *p, Type *parameter_type, ParameterValue const ¶m_value, TokenPos const &pos);
|
||||
|
||||
lbValue lb_equal_proc_for_type(lbModule *m, Type *type);
|
||||
lbValue lb_hasher_proc_for_type(lbModule *m, Type *type);
|
||||
lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t);
|
||||
gb_internal lbValue lb_equal_proc_for_type(lbModule *m, Type *type);
|
||||
gb_internal lbValue lb_hasher_proc_for_type(lbModule *m, Type *type);
|
||||
gb_internal lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t);
|
||||
|
||||
LLVMMetadataRef lb_debug_type(lbModule *m, Type *type);
|
||||
gb_internal LLVMMetadataRef lb_debug_type(lbModule *m, Type *type);
|
||||
|
||||
lbValue lb_emit_count_ones(lbProcedure *p, lbValue x, Type *type);
|
||||
lbValue lb_emit_count_zeros(lbProcedure *p, lbValue x, Type *type);
|
||||
lbValue lb_emit_count_trailing_zeros(lbProcedure *p, lbValue x, Type *type);
|
||||
lbValue lb_emit_count_leading_zeros(lbProcedure *p, lbValue x, Type *type);
|
||||
lbValue lb_emit_reverse_bits(lbProcedure *p, lbValue x, Type *type);
|
||||
gb_internal lbValue lb_emit_count_ones(lbProcedure *p, lbValue x, Type *type);
|
||||
gb_internal lbValue lb_emit_count_zeros(lbProcedure *p, lbValue x, Type *type);
|
||||
gb_internal lbValue lb_emit_count_trailing_zeros(lbProcedure *p, lbValue x, Type *type);
|
||||
gb_internal lbValue lb_emit_count_leading_zeros(lbProcedure *p, lbValue x, Type *type);
|
||||
gb_internal lbValue lb_emit_reverse_bits(lbProcedure *p, lbValue x, Type *type);
|
||||
|
||||
lbValue lb_emit_bit_set_card(lbProcedure *p, lbValue x);
|
||||
gb_internal lbValue lb_emit_bit_set_card(lbProcedure *p, lbValue x);
|
||||
|
||||
void lb_mem_zero_addr(lbProcedure *p, LLVMValueRef ptr, Type *type);
|
||||
gb_internal void lb_mem_zero_addr(lbProcedure *p, LLVMValueRef ptr, Type *type);
|
||||
|
||||
void lb_build_nested_proc(lbProcedure *p, AstProcLit *pd, Entity *e);
|
||||
lbValue lb_emit_logical_binary_expr(lbProcedure *p, TokenKind op, Ast *left, Ast *right, Type *type);
|
||||
lbValue lb_build_cond(lbProcedure *p, Ast *cond, lbBlock *true_block, lbBlock *false_block);
|
||||
gb_internal void lb_build_nested_proc(lbProcedure *p, AstProcLit *pd, Entity *e);
|
||||
gb_internal lbValue lb_emit_logical_binary_expr(lbProcedure *p, TokenKind op, Ast *left, Ast *right, Type *type);
|
||||
gb_internal lbValue lb_build_cond(lbProcedure *p, Ast *cond, lbBlock *true_block, lbBlock *false_block);
|
||||
|
||||
LLVMValueRef llvm_const_named_struct(lbModule *m, Type *t, LLVMValueRef *values, isize value_count_);
|
||||
LLVMValueRef llvm_const_named_struct_internal(LLVMTypeRef t, LLVMValueRef *values, isize value_count_);
|
||||
void lb_set_entity_from_other_modules_linkage_correctly(lbModule *other_module, Entity *e, String const &name);
|
||||
gb_internal LLVMValueRef llvm_const_named_struct(lbModule *m, Type *t, LLVMValueRef *values, isize value_count_);
|
||||
gb_internal LLVMValueRef llvm_const_named_struct_internal(LLVMTypeRef t, LLVMValueRef *values, isize value_count_);
|
||||
gb_internal void lb_set_entity_from_other_modules_linkage_correctly(lbModule *other_module, Entity *e, String const &name);
|
||||
|
||||
lbValue lb_expr_untyped_const_to_typed(lbModule *m, Ast *expr, Type *t);
|
||||
bool lb_is_expr_untyped_const(Ast *expr);
|
||||
gb_internal lbValue lb_expr_untyped_const_to_typed(lbModule *m, Ast *expr, Type *t);
|
||||
gb_internal bool lb_is_expr_untyped_const(Ast *expr);
|
||||
|
||||
LLVMValueRef llvm_alloca(lbProcedure *p, LLVMTypeRef llvm_type, isize alignment, char const *name = "");
|
||||
gb_internal LLVMValueRef llvm_alloca(lbProcedure *p, LLVMTypeRef llvm_type, isize alignment, char const *name = "");
|
||||
|
||||
void lb_mem_zero_ptr(lbProcedure *p, LLVMValueRef ptr, Type *type, unsigned alignment);
|
||||
gb_internal void lb_mem_zero_ptr(lbProcedure *p, LLVMValueRef ptr, Type *type, unsigned alignment);
|
||||
|
||||
void lb_emit_init_context(lbProcedure *p, lbAddr addr);
|
||||
gb_internal void lb_emit_init_context(lbProcedure *p, lbAddr addr);
|
||||
|
||||
|
||||
lbStructFieldRemapping lb_get_struct_remapping(lbModule *m, Type *t);
|
||||
LLVMTypeRef lb_type_padding_filler(lbModule *m, i64 padding, i64 padding_align);
|
||||
gb_internal lbStructFieldRemapping lb_get_struct_remapping(lbModule *m, Type *t);
|
||||
gb_internal LLVMTypeRef lb_type_padding_filler(lbModule *m, i64 padding, i64 padding_align);
|
||||
|
||||
LLVMValueRef llvm_basic_shuffle(lbProcedure *p, LLVMValueRef vector, LLVMValueRef mask);
|
||||
gb_internal LLVMValueRef llvm_basic_shuffle(lbProcedure *p, LLVMValueRef vector, LLVMValueRef mask);
|
||||
|
||||
LLVMValueRef lb_call_intrinsic(lbProcedure *p, const char *name, LLVMValueRef* args, unsigned arg_count, LLVMTypeRef* types, unsigned type_count);
|
||||
void lb_mem_copy_overlapping(lbProcedure *p, lbValue dst, lbValue src, lbValue len, bool is_volatile=false);
|
||||
void lb_mem_copy_non_overlapping(lbProcedure *p, lbValue dst, lbValue src, lbValue len, bool is_volatile=false);
|
||||
LLVMValueRef lb_mem_zero_ptr_internal(lbProcedure *p, LLVMValueRef ptr, LLVMValueRef len, unsigned alignment, bool is_volatile);
|
||||
gb_internal LLVMValueRef lb_call_intrinsic(lbProcedure *p, const char *name, LLVMValueRef* args, unsigned arg_count, LLVMTypeRef* types, unsigned type_count);
|
||||
gb_internal void lb_mem_copy_overlapping(lbProcedure *p, lbValue dst, lbValue src, lbValue len, bool is_volatile=false);
|
||||
gb_internal void lb_mem_copy_non_overlapping(lbProcedure *p, lbValue dst, lbValue src, lbValue len, bool is_volatile=false);
|
||||
gb_internal LLVMValueRef lb_mem_zero_ptr_internal(lbProcedure *p, LLVMValueRef ptr, LLVMValueRef len, unsigned alignment, bool is_volatile);
|
||||
|
||||
i64 lb_max_zero_init_size(void) {
|
||||
gb_internal gb_inline i64 lb_max_zero_init_size(void) {
|
||||
return cast(i64)(4*build_context.word_size);
|
||||
}
|
||||
|
||||
LLVMTypeRef OdinLLVMGetArrayElementType(LLVMTypeRef type);
|
||||
LLVMTypeRef OdinLLVMGetVectorElementType(LLVMTypeRef type);
|
||||
gb_internal LLVMTypeRef OdinLLVMGetArrayElementType(LLVMTypeRef type);
|
||||
gb_internal LLVMTypeRef OdinLLVMGetVectorElementType(LLVMTypeRef type);
|
||||
|
||||
#define LB_STARTUP_RUNTIME_PROC_NAME "__$startup_runtime"
|
||||
#define LB_STARTUP_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",
|
||||
"available externally linkage",
|
||||
"link once any linkage",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
bool lb_is_const(lbValue value) {
|
||||
gb_internal bool lb_is_const(lbValue value) {
|
||||
LLVMValueRef v = value.value;
|
||||
if (is_type_untyped_nil(value.type) || is_type_untyped_undef(value.type)) {
|
||||
// TODO(bill): Is this correct behaviour?
|
||||
@@ -10,7 +10,7 @@ bool lb_is_const(lbValue value) {
|
||||
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)) {
|
||||
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)) {
|
||||
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;
|
||||
if (LLVMIsConstant(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);
|
||||
auto v = exact_value_to_integer(expr->tav.value);
|
||||
if (v.kind == ExactValue_Integer) {
|
||||
@@ -64,7 +64,7 @@ bool lb_is_expr_constant_zero(Ast *expr) {
|
||||
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(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);
|
||||
if (src == dst) {
|
||||
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(t));
|
||||
GB_ASSERT(lb_is_const(value));
|
||||
@@ -127,7 +127,7 @@ lbValue lb_const_ptr_cast(lbModule *m, lbValue value, Type *t) {
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
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 elem_count = LLVMCountStructElementTypes(t);
|
||||
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);
|
||||
}
|
||||
|
||||
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_;
|
||||
for (unsigned i = 0; i < value_count; i++) {
|
||||
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);
|
||||
}
|
||||
|
||||
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(are_types_identical(len.type, t_int));
|
||||
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));
|
||||
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));
|
||||
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 = {};
|
||||
res.value = LLVMConstInt(lb_type(m, type), cast(unsigned long long)value, !is_type_unsigned(type));
|
||||
res.type = type;
|
||||
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));
|
||||
}
|
||||
|
||||
|
||||
lbValue lb_const_bool(lbModule *m, Type *type, bool value) {
|
||||
gb_internal lbValue lb_const_bool(lbModule *m, Type *type, bool value) {
|
||||
lbValue res = {};
|
||||
res.value = LLVMConstInt(lb_type(m, type), value, false);
|
||||
res.type = type;
|
||||
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);
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
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);
|
||||
u32 u = bit_cast<u32>(f);
|
||||
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);
|
||||
if (is_type_untyped(tv.type)) {
|
||||
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));
|
||||
auto const &tv = type_and_value_of_expr(expr);
|
||||
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;
|
||||
|
||||
LLVMValueRef fields[4] = {};
|
||||
@@ -271,7 +271,7 @@ lbValue lb_emit_source_code_location_const(lbProcedure *p, String const &procedu
|
||||
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 = {};
|
||||
if (p->entity) {
|
||||
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);
|
||||
lbAddr addr = lb_add_global_generated(p->module, loc.type, loc, nullptr);
|
||||
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);
|
||||
lbAddr addr = lb_add_global_generated(p->module, loc.type, loc, nullptr);
|
||||
lb_make_global_private_const(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));
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
|
||||
|
||||
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_const = true;
|
||||
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);
|
||||
}
|
||||
|
||||
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)) {
|
||||
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;
|
||||
|
||||
type = default_type(type);
|
||||
|
||||
@@ -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) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -8,20 +8,14 @@ LLVMMetadataRef lb_get_llvm_metadata(lbModule *m, void *key) {
|
||||
}
|
||||
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) {
|
||||
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));
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
GB_ASSERT_MSG(scope != nullptr, "%.*s", LIT(p->name));
|
||||
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);
|
||||
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);
|
||||
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
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
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)
|
||||
);
|
||||
}
|
||||
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;
|
||||
GB_ASSERT(pkg->files.count != 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);
|
||||
#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);
|
||||
@@ -127,7 +121,7 @@ LLVMMetadataRef lb_debug_type_basic_type(lbModule *m, String const &name, u64 si
|
||||
#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
|
||||
gb_unused(size);
|
||||
|
||||
@@ -474,7 +468,7 @@ LLVMMetadataRef lb_debug_type_internal(lbModule *m, Type *type) {
|
||||
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;
|
||||
for (;;) {
|
||||
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);
|
||||
LLVMMetadataRef found = lb_get_llvm_metadata(m, type);
|
||||
if (found != nullptr) {
|
||||
@@ -615,7 +609,7 @@ LLVMMetadataRef lb_debug_type(lbModule *m, Type *type) {
|
||||
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_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) {
|
||||
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);
|
||||
}
|
||||
|
||||
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) {
|
||||
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) {
|
||||
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;
|
||||
if (e->pkg && e->pkg->name.len > 0) {
|
||||
// NOTE(bill): C++ NONSENSE FOR DEBUG SHITE!
|
||||
@@ -1135,7 +1129,7 @@ String debug_info_mangle_constant_name(Entity *e, bool *did_allocate_) {
|
||||
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 file = nullptr;
|
||||
unsigned line = 0;
|
||||
@@ -1151,7 +1145,7 @@ void add_debug_info_global_variable_expr(lbModule *m, String const &name, LLVMMe
|
||||
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);
|
||||
|
||||
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) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
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) {
|
||||
case Token_Add:
|
||||
return x;
|
||||
@@ -283,7 +283,7 @@ lbValue lb_emit_unary_arith(lbProcedure *p, TokenKind op, lbValue x, Type *type)
|
||||
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));
|
||||
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));
|
||||
|
||||
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);
|
||||
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);
|
||||
GB_ASSERT(mt->kind == Type_Matrix);
|
||||
LLVMTypeRef elem_type = lb_type(p->module, mt->Matrix.elem);
|
||||
@@ -554,7 +554,7 @@ LLVMValueRef lb_matrix_to_vector(lbProcedure *p, lbValue matrix) {
|
||||
#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);
|
||||
GB_ASSERT(mt->kind == Type_Matrix);
|
||||
|
||||
@@ -574,7 +574,7 @@ LLVMValueRef lb_matrix_trimmed_vector_mask(lbProcedure *p, Type *mt) {
|
||||
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);
|
||||
|
||||
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)) {
|
||||
i32 rank = type_math_rank(m.type);
|
||||
if (rank == 2) {
|
||||
@@ -669,7 +669,7 @@ lbValue lb_emit_matrix_tranpose(lbProcedure *p, lbValue m, Type *type) {
|
||||
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);
|
||||
LLVMValueRef res_ptr = res.addr.value;
|
||||
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);
|
||||
}
|
||||
|
||||
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)) {
|
||||
// no-op
|
||||
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 *at = base_type(a.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
|
||||
|
||||
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
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
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));
|
||||
|
||||
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)) {
|
||||
return lb_emit_arith_array(p, op, lhs, rhs, type);
|
||||
} else if (is_type_matrix(lhs.type) || is_type_matrix(rhs.type)) {
|
||||
@@ -1325,7 +1325,7 @@ handle_op:
|
||||
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);
|
||||
|
||||
TypeAndValue tv = type_and_value_of_expr(expr);
|
||||
@@ -1472,7 +1472,7 @@ lbValue lb_build_binary_expr(lbProcedure *p, Ast *expr) {
|
||||
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;
|
||||
t = reduce_tuple_to_single_type(t);
|
||||
|
||||
@@ -2202,7 +2202,7 @@ lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) {
|
||||
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));
|
||||
lbValue left_ptr = lb_address_from_load_or_generate_local(p, left);
|
||||
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 *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 = {};
|
||||
res.type = t_llvm_bool;
|
||||
Type *t = x.type;
|
||||
@@ -2803,7 +2803,7 @@ lbValue lb_emit_comp_against_nil(lbProcedure *p, TokenKind op_kind, lbValue x) {
|
||||
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);
|
||||
lbValue ptr = lb_emit_struct_ep(p, v.addr, 0);
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
lbValue lb_build_expr_internal(lbProcedure *p, Ast *expr);
|
||||
lbValue lb_build_expr(lbProcedure *p, Ast *expr) {
|
||||
gb_internal lbValue lb_build_expr_internal(lbProcedure *p, Ast *expr);
|
||||
gb_internal lbValue lb_build_expr(lbProcedure *p, Ast *expr) {
|
||||
u16 prev_state_flags = p->state_flags;
|
||||
defer (p->state_flags = prev_state_flags);
|
||||
|
||||
@@ -3080,7 +3080,7 @@ lbValue lb_build_expr(lbProcedure *p, Ast *expr) {
|
||||
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;
|
||||
|
||||
expr = unparen_expr(expr);
|
||||
@@ -3355,10 +3355,10 @@ lbValue lb_build_expr_internal(lbProcedure *p, Ast *expr) {
|
||||
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);
|
||||
}
|
||||
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);
|
||||
String name = e->token.string;
|
||||
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);
|
||||
if (e->kind == Entity_Constant) {
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
lbAddr addr = lb_build_addr(p, ce->args[0]);
|
||||
if (index_count == 0) {
|
||||
@@ -3463,8 +3463,8 @@ lbAddr lb_build_array_swizzle_addr(lbProcedure *p, AstCallExpr *ce, TypeAndValue
|
||||
}
|
||||
|
||||
|
||||
lbAddr lb_build_addr_internal(lbProcedure *p, Ast *expr);
|
||||
lbAddr lb_build_addr(lbProcedure *p, Ast *expr) {
|
||||
gb_internal lbAddr lb_build_addr_internal(lbProcedure *p, Ast *expr);
|
||||
gb_internal lbAddr lb_build_addr(lbProcedure *p, Ast *expr) {
|
||||
expr = unparen_expr(expr);
|
||||
|
||||
// IMPORTANT NOTE(bill):
|
||||
@@ -3489,7 +3489,7 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) {
|
||||
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 *et = nullptr;
|
||||
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) {
|
||||
auto td = temp_data[i];
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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) {
|
||||
case_ast_node(i, Implicit, expr);
|
||||
lbAddr v = {};
|
||||
|
||||
@@ -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 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;
|
||||
|
||||
|
||||
void lb_init_module(lbModule *m, Checker *c) {
|
||||
gb_internal void lb_init_module(lbModule *m, Checker *c) {
|
||||
m->info = &c->info;
|
||||
|
||||
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) {
|
||||
return false;
|
||||
}
|
||||
@@ -137,8 +137,8 @@ bool lb_init_generator(lbGenerator *gen, Checker *c) {
|
||||
ptr_set_init(&gen->foreign_libraries_set, heap_allocator(), 1024);
|
||||
|
||||
if (USE_SEPARATE_MODULES) {
|
||||
for_array(i, gen->info->packages.entries) {
|
||||
AstPackage *pkg = gen->info->packages.entries[i].value;
|
||||
for (auto const &entry : gen->info->packages) {
|
||||
AstPackage *pkg = entry.value;
|
||||
|
||||
auto m = gb_alloc_item(permanent_allocator(), lbModule);
|
||||
m->pkg = pkg;
|
||||
@@ -153,8 +153,8 @@ bool lb_init_generator(lbGenerator *gen, Checker *c) {
|
||||
lb_init_module(&gen->default_module, c);
|
||||
|
||||
|
||||
for_array(i, gen->modules.entries) {
|
||||
lbModule *m = gen->modules.entries[i].value;
|
||||
for (auto const &entry : gen->modules) {
|
||||
lbModule *m = entry.value;
|
||||
LLVMContextRef ctx = LLVMGetModuleContext(m->mod);
|
||||
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);
|
||||
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 = {};
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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) {
|
||||
lb_emit_increment(p, data.idx_addr.addr);
|
||||
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);
|
||||
LLVMSetUnnamedAddress(global_data, LLVMGlobalUnnamedAddr);
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 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));
|
||||
Type *type = type_deref(value.type);
|
||||
|
||||
@@ -251,7 +251,7 @@ lbValue lb_emit_epi(lbProcedure *p, lbValue const &value, isize index) {
|
||||
return res;
|
||||
}
|
||||
// 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(LLVMIsConstant(value.value));
|
||||
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);
|
||||
}
|
||||
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);
|
||||
|
||||
LLVMValueRef val = LLVMBuildAlloca(p->builder, llvm_type, name);
|
||||
@@ -290,20 +284,20 @@ LLVMValueRef llvm_alloca(lbProcedure *p, LLVMTypeRef llvm_type, isize alignment,
|
||||
return val;
|
||||
}
|
||||
|
||||
lbValue lb_zero(lbModule *m, Type *t) {
|
||||
gb_internal lbValue lb_zero(lbModule *m, Type *t) {
|
||||
lbValue v = {};
|
||||
v.value = LLVMConstInt(lb_type(m, t), 0, false);
|
||||
v.type = t;
|
||||
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);
|
||||
unsigned indices[1] = {0};
|
||||
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) {
|
||||
LLVMOpcode op = LLVMGetInstructionOpcode(instr);
|
||||
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);
|
||||
if (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};
|
||||
if (addr.type != nullptr && is_type_relative_pointer(type_deref(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));
|
||||
Type *mt = type_deref(addr.type);
|
||||
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};
|
||||
v.soa.index = index;
|
||||
v.soa.index_expr = index_expr;
|
||||
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(1 < swizzle_count && swizzle_count <= 4);
|
||||
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;
|
||||
}
|
||||
|
||||
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));
|
||||
lbAddr v = {lbAddr_SwizzleLarge, addr};
|
||||
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;
|
||||
}
|
||||
|
||||
Type *lb_addr_type(lbAddr const &addr) {
|
||||
gb_internal Type *lb_addr_type(lbAddr const &addr) {
|
||||
if (addr.addr.value == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -411,7 +405,7 @@ Type *lb_addr_type(lbAddr const &addr) {
|
||||
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) {
|
||||
GB_PANIC("Illegal addr -> nullptr");
|
||||
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);
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
|
||||
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) {
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
|
||||
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) {
|
||||
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)) {
|
||||
return LLVMGetAlignment(addr_ptr);
|
||||
}
|
||||
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 (LLVMGetAlignment(addr_ptr) < alignment) {
|
||||
if (LLVMIsAAllocaInst(addr_ptr) || LLVMIsAGlobalValue(addr_ptr)) {
|
||||
@@ -604,15 +598,15 @@ bool lb_try_update_alignment(LLVMValueRef addr_ptr, unsigned alignment) {
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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));
|
||||
GB_ASSERT(is_type_array_like(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;
|
||||
}
|
||||
|
||||
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) {
|
||||
return;
|
||||
}
|
||||
@@ -874,15 +868,7 @@ void lb_addr_store(lbProcedure *p, lbAddr addr, lbValue value) {
|
||||
lb_emit_store(p, addr.addr, value);
|
||||
}
|
||||
|
||||
void lb_const_store(lbValue ptr, lbValue value) {
|
||||
GB_ASSERT(lb_is_const(ptr));
|
||||
GB_ASSERT(lb_is_const(value));
|
||||
GB_ASSERT(is_type_pointer(ptr.type));
|
||||
LLVMSetInitializer(ptr.value, value.value);
|
||||
}
|
||||
|
||||
|
||||
bool lb_is_type_proc_recursive(Type *t) {
|
||||
gb_internal bool lb_is_type_proc_recursive(Type *t) {
|
||||
for (;;) {
|
||||
if (t == nullptr) {
|
||||
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);
|
||||
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));
|
||||
}
|
||||
|
||||
lbValue lb_emit_load(lbProcedure *p, lbValue value) {
|
||||
gb_internal lbValue lb_emit_load(lbProcedure *p, lbValue value) {
|
||||
GB_ASSERT(value.value != nullptr);
|
||||
if (is_type_multi_pointer(value.type)) {
|
||||
Type *vt = base_type(value.type);
|
||||
@@ -1003,7 +989,7 @@ lbValue lb_emit_load(lbProcedure *p, lbValue value) {
|
||||
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);
|
||||
|
||||
|
||||
@@ -1243,11 +1229,11 @@ lbValue lb_addr_load(lbProcedure *p, lbAddr const &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)));
|
||||
}
|
||||
|
||||
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;
|
||||
GB_ASSERT_MSG(is_type_pointer(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;
|
||||
}
|
||||
|
||||
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 tag_ptr = lb_emit_union_tag_ptr(p, 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);
|
||||
|
||||
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));
|
||||
GB_ASSERT(pt->kind == Type_Union);
|
||||
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);
|
||||
LLVMTypeRef *fields = gb_alloc_array(temporary_allocator(), LLVMTypeRef, field_count);
|
||||
LLVMGetStructElementTypes(src, fields);
|
||||
LLVMStructSetBody(dst, fields, field_count, LLVMIsPackedStruct(src));
|
||||
}
|
||||
|
||||
LLVMTypeRef lb_alignment_prefix_type_hack(lbModule *m, i64 alignment) {
|
||||
switch (alignment) {
|
||||
case 1:
|
||||
return LLVMArrayType(lb_type(m, t_u8), 0);
|
||||
case 2:
|
||||
return LLVMArrayType(lb_type(m, t_u16), 0);
|
||||
case 4:
|
||||
return LLVMArrayType(lb_type(m, t_u32), 0);
|
||||
case 8:
|
||||
return LLVMArrayType(lb_type(m, t_u64), 0);
|
||||
default: case 16:
|
||||
return LLVMArrayType(LLVMVectorType(lb_type(m, t_u32), 4), 0);
|
||||
}
|
||||
}
|
||||
|
||||
String lb_mangle_name(lbModule *m, Entity *e) {
|
||||
gb_internal String lb_mangle_name(lbModule *m, Entity *e) {
|
||||
String name = e->token.string;
|
||||
|
||||
AstPackage *pkg = e->pkg;
|
||||
@@ -1384,7 +1355,7 @@ String lb_mangle_name(lbModule *m, Entity *e) {
|
||||
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
|
||||
// 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) {
|
||||
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 = base_type(original_type);
|
||||
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;
|
||||
|
||||
}
|
||||
LLVMTypeRef lb_type_internal(lbModule *m, Type *type) {
|
||||
gb_internal LLVMTypeRef lb_type_internal(lbModule *m, Type *type) {
|
||||
LLVMContextRef ctx = m->ctx;
|
||||
i64 size = type_size_of(type); // Check size
|
||||
gb_unused(size);
|
||||
@@ -2145,7 +2116,7 @@ LLVMTypeRef lb_type_internal(lbModule *m, Type *type) {
|
||||
return LLVMInt32TypeInContext(ctx);
|
||||
}
|
||||
|
||||
LLVMTypeRef lb_type(lbModule *m, Type *type) {
|
||||
gb_internal LLVMTypeRef lb_type(lbModule *m, Type *type) {
|
||||
type = default_type(type);
|
||||
|
||||
LLVMTypeRef *found = map_get(&m->types, type);
|
||||
@@ -2164,7 +2135,7 @@ LLVMTypeRef lb_type(lbModule *m, Type *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;
|
||||
ft_found = map_get(&m->function_type_map, pt);
|
||||
if (!ft_found) {
|
||||
@@ -2177,7 +2148,7 @@ lbFunctionType *lb_get_function_type(lbModule *m, Type *pt) {
|
||||
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) {
|
||||
return;
|
||||
}
|
||||
@@ -2192,20 +2163,17 @@ void lb_ensure_abi_function_type(lbModule *m, lbProcedure *p) {
|
||||
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) {
|
||||
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) {
|
||||
string_map_set(&m->members, name, val);
|
||||
}
|
||||
}
|
||||
void lb_add_member(lbModule *m, StringHashKey const &key, lbValue val) {
|
||||
string_map_set(&m->members, key, val);
|
||||
}
|
||||
void lb_add_procedure_value(lbModule *m, lbProcedure *p) {
|
||||
gb_internal void lb_add_procedure_value(lbModule *m, lbProcedure *p) {
|
||||
if (p->entity != nullptr) {
|
||||
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;
|
||||
String s = make_string_c(name);
|
||||
|
||||
@@ -2243,7 +2211,7 @@ LLVMAttributeRef lb_create_enum_attribute_with_type(LLVMContextRef ctx, char con
|
||||
#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);
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
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);
|
||||
GB_ASSERT(attr != nullptr);
|
||||
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);
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
|
||||
|
||||
void lb_add_edge(lbBlock *from, lbBlock *to) {
|
||||
gb_internal void lb_add_edge(lbBlock *from, lbBlock *to) {
|
||||
LLVMValueRef instr = LLVMGetLastInstruction(from->block);
|
||||
if (instr == nullptr || !LLVMIsATerminatorInst(instr)) {
|
||||
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);
|
||||
b->block = LLVMCreateBasicBlockInContext(p->module->ctx, name);
|
||||
b->appended = false;
|
||||
@@ -2309,7 +2277,7 @@ lbBlock *lb_create_block(lbProcedure *p, char const *name, bool append) {
|
||||
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) {
|
||||
return;
|
||||
}
|
||||
@@ -2323,7 +2291,7 @@ void lb_emit_jump(lbProcedure *p, lbBlock *target_block) {
|
||||
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;
|
||||
if (b == nullptr) {
|
||||
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);
|
||||
}
|
||||
LLVMTypeRef OdinLLVMGetArrayElementType(LLVMTypeRef type) {
|
||||
gb_internal LLVMTypeRef OdinLLVMGetArrayElementType(LLVMTypeRef type) {
|
||||
GB_ASSERT(lb_is_type_kind(type, LLVMArrayTypeKind));
|
||||
return OdinLLVMGetInternalElementType(type);
|
||||
}
|
||||
LLVMTypeRef OdinLLVMGetVectorElementType(LLVMTypeRef type) {
|
||||
gb_internal LLVMTypeRef OdinLLVMGetVectorElementType(LLVMTypeRef type) {
|
||||
GB_ASSERT(lb_is_type_kind(type, LLVMVectorTypeKind));
|
||||
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;
|
||||
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);
|
||||
LLVMValueRef *found = string_map_get(&m->const_strings, key);
|
||||
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;
|
||||
if (str.len != 0) {
|
||||
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;
|
||||
}
|
||||
|
||||
lbValue lb_find_or_add_entity_string_byte_slice(lbModule *m, String const &str) {
|
||||
LLVMValueRef indices[2] = {llvm_zero(m), llvm_zero(m)};
|
||||
LLVMValueRef data = LLVMConstStringInContext(m->ctx,
|
||||
cast(char const *)str.text,
|
||||
cast(unsigned)str.len,
|
||||
false);
|
||||
|
||||
|
||||
char *name = nullptr;
|
||||
{
|
||||
isize max_len = 7+8+1;
|
||||
name = gb_alloc_array(permanent_allocator(), char, max_len);
|
||||
u32 id = m->gen->global_array_index.fetch_add(1);
|
||||
isize len = gb_snprintf(name, max_len, "csbs$%x", id);
|
||||
len -= 1;
|
||||
}
|
||||
LLVMTypeRef type = LLVMTypeOf(data);
|
||||
LLVMValueRef global_data = LLVMAddGlobal(m->mod, type, name);
|
||||
LLVMSetInitializer(global_data, data);
|
||||
lb_make_global_private_const(global_data);
|
||||
LLVMSetAlignment(global_data, 1);
|
||||
|
||||
LLVMValueRef ptr = nullptr;
|
||||
if (str.len != 0) {
|
||||
ptr = LLVMConstInBoundsGEP2(type, global_data, indices, 2);
|
||||
} else {
|
||||
ptr = LLVMConstNull(lb_type(m, t_u8_ptr));
|
||||
}
|
||||
LLVMValueRef len = LLVMConstInt(lb_type(m, t_int), str.len, true);
|
||||
LLVMValueRef values[2] = {ptr, len};
|
||||
|
||||
lbValue res = {};
|
||||
res.value = llvm_const_named_struct(m, t_u8_slice, values, 2);
|
||||
res.type = t_u8_slice;
|
||||
return res;
|
||||
}
|
||||
lbValue lb_find_or_add_entity_string_byte_slice_with_type(lbModule *m, String const &str, Type *slice_type) {
|
||||
gb_internal lbValue lb_find_or_add_entity_string_byte_slice_with_type(lbModule *m, String const &str, Type *slice_type) {
|
||||
GB_ASSERT(is_type_slice(slice_type));
|
||||
LLVMValueRef indices[2] = {llvm_zero(m), llvm_zero(m)};
|
||||
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) {
|
||||
// NOTE(bill): Bypass the stack copied variable for
|
||||
// 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));
|
||||
e = strip_entity_wrapping(e);
|
||||
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);
|
||||
type = default_type(type);
|
||||
|
||||
@@ -2700,23 +2632,23 @@ lbAddr lb_add_global_generated(lbModule *m, Type *type, lbValue value, Entity **
|
||||
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;
|
||||
Entity *e = scope_lookup_current(p->scope, name);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
GB_ASSERT(e != nullptr);
|
||||
|
||||
@@ -2788,7 +2720,7 @@ lbValue lb_find_value_from_entity(lbModule *m, Entity *e) {
|
||||
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};
|
||||
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(true_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);
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
lb_try_update_alignment(res.addr, cast(unsigned)min_alignment);
|
||||
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) {
|
||||
LLVMSetLinkage(value, LLVMInternalLinkage);
|
||||
} else if (flags & EntityFlag_CustomLinkage_Strong) {
|
||||
|
||||
@@ -32,21 +32,21 @@
|
||||
**************************************************************************/
|
||||
|
||||
|
||||
void lb_populate_function_pass_manager(lbModule *m, LLVMPassManagerRef fpm, bool ignore_memcpy_pass, i32 optimization_level);
|
||||
void lb_add_function_simplifcation_passes(LLVMPassManagerRef mpm, i32 optimization_level);
|
||||
void lb_populate_module_pass_manager(LLVMTargetMachineRef target_machine, LLVMPassManagerRef mpm, i32 optimization_level);
|
||||
void lb_populate_function_pass_manager_specific(lbModule *m, LLVMPassManagerRef fpm, i32 optimization_level);
|
||||
gb_internal void lb_populate_function_pass_manager(lbModule *m, LLVMPassManagerRef fpm, bool ignore_memcpy_pass, i32 optimization_level);
|
||||
gb_internal void lb_add_function_simplifcation_passes(LLVMPassManagerRef mpm, i32 optimization_level);
|
||||
gb_internal void lb_populate_module_pass_manager(LLVMTargetMachineRef target_machine, LLVMPassManagerRef mpm, i32 optimization_level);
|
||||
gb_internal void lb_populate_function_pass_manager_specific(lbModule *m, LLVMPassManagerRef fpm, i32 optimization_level);
|
||||
|
||||
LLVMBool lb_must_preserve_predicate_callback(LLVMValueRef value, void *user_data) {
|
||||
lbModule *m = cast(lbModule *)user_data;
|
||||
if (m == nullptr) {
|
||||
return false;
|
||||
}
|
||||
if (value == nullptr) {
|
||||
return false;
|
||||
}
|
||||
return LLVMIsAAllocaInst(value) != nullptr;
|
||||
}
|
||||
// gb_internal LLVMBool lb_must_preserve_predicate_callback(LLVMValueRef value, void *user_data) {
|
||||
// lbModule *m = cast(lbModule *)user_data;
|
||||
// if (m == nullptr) {
|
||||
// return false;
|
||||
// }
|
||||
// if (value == nullptr) {
|
||||
// return false;
|
||||
// }
|
||||
// return LLVMIsAAllocaInst(value) != nullptr;
|
||||
// }
|
||||
|
||||
|
||||
#if LLVM_VERSION_MAJOR < 12
|
||||
@@ -55,7 +55,7 @@ LLVMBool lb_must_preserve_predicate_callback(LLVMValueRef value, void *user_data
|
||||
#define LLVM_ADD_CONSTANT_VALUE_PASS(fpm)
|
||||
#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) {
|
||||
LLVMAddMergedLoadStoreMotionPass(fpm);
|
||||
} 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
|
||||
// TODO(bill): Determine which opt definitions should exist in the first place
|
||||
optimization_level = gb_clamp(optimization_level, 0, 2);
|
||||
@@ -102,7 +102,7 @@ void lb_populate_function_pass_manager(lbModule *m, LLVMPassManagerRef fpm, bool
|
||||
#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
|
||||
// TODO(bill): Determine which opt definitions should exist in the first place
|
||||
optimization_level = gb_clamp(optimization_level, 0, 2);
|
||||
@@ -141,7 +141,7 @@ void lb_populate_function_pass_manager_specific(lbModule *m, LLVMPassManagerRef
|
||||
#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);
|
||||
|
||||
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
|
||||
// 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
|
||||
**************************************************************************/
|
||||
|
||||
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 pass_count = 0;
|
||||
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);
|
||||
// NOTE(bill): LLVMAddDCEPass doesn't seem to be exported in the official DLL's for LLVM
|
||||
// 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);
|
||||
}
|
||||
|
||||
void llvm_delete_function(LLVMValueRef func) {
|
||||
gb_internal void llvm_delete_function(LLVMValueRef func) {
|
||||
// for (LLVMBasicBlockRef block = LLVMGetFirstBasicBlock(func); block != nullptr; /**/) {
|
||||
// LLVMBasicBlockRef curr_block = block;
|
||||
// block = LLVMGetNextBasicBlock(block);
|
||||
@@ -382,7 +382,7 @@ void llvm_delete_function(LLVMValueRef 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 *constants;
|
||||
@@ -419,7 +419,7 @@ void lb_append_to_compiler_used(lbModule *m, LLVMValueRef func) {
|
||||
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 pass_count = 0;
|
||||
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 pass_count = 0;
|
||||
isize const max_pass_count = 10;
|
||||
|
||||
@@ -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));
|
||||
GB_ASSERT_MSG(id != 0, "Unable to find %s", name);
|
||||
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, "");
|
||||
}
|
||||
|
||||
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);
|
||||
src = lb_emit_conv(p, src, t_rawptr);
|
||||
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);
|
||||
src = lb_emit_conv(p, src, t_rawptr);
|
||||
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->kind == Entity_Procedure);
|
||||
if (!entity->Procedure.is_foreign) {
|
||||
@@ -320,7 +319,7 @@ lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool ignore_body)
|
||||
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);
|
||||
GB_ASSERT_MSG(found == nullptr, "failed to create dummy procedure for: %.*s", LIT(link_name));
|
||||
@@ -384,50 +383,50 @@ lbProcedure *lb_create_dummy_procedure(lbModule *m, String link_name, Type *type
|
||||
}
|
||||
|
||||
|
||||
lbValue lb_value_param(lbProcedure *p, Entity *e, Type *abi_type, i32 index, lbParamPasskind *kind_) {
|
||||
lbParamPasskind kind = lbParamPass_Value;
|
||||
// gb_internal lbValue lb_value_param(lbProcedure *p, Entity *e, Type *abi_type, i32 index, lbParamPasskind *kind_) {
|
||||
// lbParamPasskind kind = lbParamPass_Value;
|
||||
|
||||
if (e != nullptr && !are_types_identical(abi_type, e->type)) {
|
||||
if (is_type_pointer(abi_type)) {
|
||||
GB_ASSERT(e->kind == Entity_Variable);
|
||||
Type *av = core_type(type_deref(abi_type));
|
||||
if (are_types_identical(av, core_type(e->type))) {
|
||||
kind = lbParamPass_Pointer;
|
||||
if (e->flags&EntityFlag_Value) {
|
||||
kind = lbParamPass_ConstRef;
|
||||
}
|
||||
} else {
|
||||
kind = lbParamPass_BitCast;
|
||||
}
|
||||
} else if (is_type_integer(abi_type)) {
|
||||
kind = lbParamPass_Integer;
|
||||
} else if (abi_type == t_llvm_bool) {
|
||||
kind = lbParamPass_Value;
|
||||
} else if (is_type_boolean(abi_type)) {
|
||||
kind = lbParamPass_Integer;
|
||||
} else if (is_type_simd_vector(abi_type)) {
|
||||
kind = lbParamPass_BitCast;
|
||||
} else if (is_type_float(abi_type)) {
|
||||
kind = lbParamPass_BitCast;
|
||||
} else if (is_type_tuple(abi_type)) {
|
||||
kind = lbParamPass_Tuple;
|
||||
} else if (is_type_proc(abi_type)) {
|
||||
kind = lbParamPass_Value;
|
||||
} else {
|
||||
GB_PANIC("Invalid abi type pass kind %s", type_to_string(abi_type));
|
||||
}
|
||||
}
|
||||
// if (e != nullptr && !are_types_identical(abi_type, e->type)) {
|
||||
// if (is_type_pointer(abi_type)) {
|
||||
// GB_ASSERT(e->kind == Entity_Variable);
|
||||
// Type *av = core_type(type_deref(abi_type));
|
||||
// if (are_types_identical(av, core_type(e->type))) {
|
||||
// kind = lbParamPass_Pointer;
|
||||
// if (e->flags&EntityFlag_Value) {
|
||||
// kind = lbParamPass_ConstRef;
|
||||
// }
|
||||
// } else {
|
||||
// kind = lbParamPass_BitCast;
|
||||
// }
|
||||
// } else if (is_type_integer(abi_type)) {
|
||||
// kind = lbParamPass_Integer;
|
||||
// } else if (abi_type == t_llvm_bool) {
|
||||
// kind = lbParamPass_Value;
|
||||
// } else if (is_type_boolean(abi_type)) {
|
||||
// kind = lbParamPass_Integer;
|
||||
// } else if (is_type_simd_vector(abi_type)) {
|
||||
// kind = lbParamPass_BitCast;
|
||||
// } else if (is_type_float(abi_type)) {
|
||||
// kind = lbParamPass_BitCast;
|
||||
// } else if (is_type_tuple(abi_type)) {
|
||||
// kind = lbParamPass_Tuple;
|
||||
// } else if (is_type_proc(abi_type)) {
|
||||
// kind = lbParamPass_Value;
|
||||
// } else {
|
||||
// GB_PANIC("Invalid abi type pass kind %s", type_to_string(abi_type));
|
||||
// }
|
||||
// }
|
||||
|
||||
if (kind_) *kind_ = kind;
|
||||
lbValue res = {};
|
||||
res.value = LLVMGetParam(p->value, cast(unsigned)index);
|
||||
res.type = abi_type;
|
||||
return res;
|
||||
}
|
||||
// if (kind_) *kind_ = kind;
|
||||
// lbValue res = {};
|
||||
// res.value = LLVMGetParam(p->value, cast(unsigned)index);
|
||||
// res.type = abi_type;
|
||||
// return res;
|
||||
// }
|
||||
|
||||
|
||||
|
||||
void lb_start_block(lbProcedure *p, lbBlock *b) {
|
||||
gb_internal void lb_start_block(lbProcedure *p, lbBlock *b) {
|
||||
GB_ASSERT(b != nullptr);
|
||||
if (!b->appended) {
|
||||
b->appended = true;
|
||||
@@ -437,7 +436,7 @@ void lb_start_block(lbProcedure *p, lbBlock *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) {
|
||||
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) {
|
||||
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);
|
||||
if (decl != nullptr) {
|
||||
for_array(i, decl->labels) {
|
||||
@@ -686,7 +685,7 @@ void lb_begin_procedure_body(lbProcedure *p) {
|
||||
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);
|
||||
|
||||
LLVMPositionBuilderAtEnd(p->builder, p->decl_block->block);
|
||||
@@ -720,11 +719,11 @@ void lb_end_procedure_body(lbProcedure *p) {
|
||||
p->curr_block = nullptr;
|
||||
p->state_flags = 0;
|
||||
}
|
||||
void lb_end_procedure(lbProcedure *p) {
|
||||
gb_internal void lb_end_procedure(lbProcedure *p) {
|
||||
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);
|
||||
lbModule *m = p->module;
|
||||
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 = {};
|
||||
Type *t = base_type(value.type);
|
||||
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)));
|
||||
|
||||
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;
|
||||
Entity *e = scope_lookup_current(pkg->scope, name);
|
||||
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);
|
||||
lbValue proc = lb_lookup_runtime_procedure(p->module, name);
|
||||
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 = {};
|
||||
Type *t = val.type;
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
Type *pt = base_type(value.type);
|
||||
@@ -1166,15 +1165,7 @@ lbValue lb_emit_call(lbProcedure *p, lbValue value, Array<lbValue> const &args,
|
||||
return result;
|
||||
}
|
||||
|
||||
LLVMValueRef llvm_splat_float(i64 count, LLVMTypeRef type, f64 value) {
|
||||
LLVMValueRef v = LLVMConstReal(type, value);
|
||||
LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, count);
|
||||
for (i64 i = 0; i < count; i++) {
|
||||
values[i] = v;
|
||||
}
|
||||
return LLVMConstVector(values, cast(unsigned)count);
|
||||
}
|
||||
LLVMValueRef llvm_splat_int(i64 count, LLVMTypeRef type, i64 value, bool is_signed=false) {
|
||||
gb_internal LLVMValueRef llvm_splat_int(i64 count, LLVMTypeRef type, i64 value, bool is_signed=false) {
|
||||
LLVMValueRef v = LLVMConstInt(type, value, is_signed);
|
||||
LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, count);
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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 ¶m_value, TokenPos const &pos) {
|
||||
gb_internal lbValue lb_handle_param_value(lbProcedure *p, Type *parameter_type, ParameterValue const ¶m_value, TokenPos const &pos) {
|
||||
switch (param_value.kind) {
|
||||
case ParameterValue_Constant:
|
||||
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);
|
||||
ast_node(ce, CallExpr, expr);
|
||||
|
||||
@@ -3030,7 +3021,7 @@ lbValue lb_build_call_expr(lbProcedure *p, Ast *expr) {
|
||||
}
|
||||
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;
|
||||
|
||||
TypeAndValue tv = type_and_value_of_expr(expr);
|
||||
|
||||
@@ -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) {
|
||||
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) {
|
||||
Ast *stmt = stmts[i];
|
||||
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);
|
||||
Entity *e = entity_of_node(ident);
|
||||
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);
|
||||
tl->prev = p->target_list;
|
||||
tl->break_ = break_;
|
||||
@@ -170,11 +170,11 @@ lbTargetList *lb_push_target_list(lbProcedure *p, Ast *label, lbBlock *break_, l
|
||||
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;
|
||||
}
|
||||
|
||||
void lb_open_scope(lbProcedure *p, Scope *s) {
|
||||
gb_internal void lb_open_scope(lbProcedure *p, Scope *s) {
|
||||
lbModule *m = p->module;
|
||||
if (m->debug_builder) {
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
GB_ASSERT(is_type_boolean(tv.type));
|
||||
GB_ASSERT(tv.value.kind == ExactValue_Bool);
|
||||
@@ -253,8 +253,8 @@ void lb_build_when_stmt(lbProcedure *p, AstWhenStmt *ws) {
|
||||
|
||||
|
||||
|
||||
void lb_build_range_indexed(lbProcedure *p, lbValue expr, Type *val_type, lbValue count_ptr,
|
||||
lbValue *val_, lbValue *idx_, lbBlock **loop_, lbBlock **done_) {
|
||||
gb_internal void lb_build_range_indexed(lbProcedure *p, lbValue expr, Type *val_type, lbValue count_ptr,
|
||||
lbValue *val_, lbValue *idx_, lbBlock **loop_, lbBlock **done_) {
|
||||
lbModule *m = p->module;
|
||||
|
||||
lbValue count = {};
|
||||
@@ -342,7 +342,7 @@ void lb_build_range_indexed(lbProcedure *p, lbValue expr, Type *val_type, lbValu
|
||||
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 elem_sz = type_size_of(type);
|
||||
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);
|
||||
}
|
||||
|
||||
void lb_map_kvh_data_static(lbProcedure *p, lbValue map_value, lbValue *ks_, lbValue *vs_, lbValue *hs_) {
|
||||
lbValue capacity = lb_map_cap(p, map_value);
|
||||
lbValue ks = lb_map_data_uintptr(p, map_value);
|
||||
lbValue vs = {};
|
||||
lbValue hs = {};
|
||||
if (ks_) *ks_ = ks;
|
||||
if (vs_) *vs_ = vs;
|
||||
if (hs_) *hs_ = hs;
|
||||
}
|
||||
|
||||
lbValue lb_map_hash_is_valid(lbProcedure *p, lbValue hash) {
|
||||
gb_internal lbValue lb_map_hash_is_valid(lbProcedure *p, lbValue hash) {
|
||||
// N :: size_of(uintptr)*8 - 1
|
||||
// (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);
|
||||
}
|
||||
|
||||
void lb_build_range_map(lbProcedure *p, lbValue expr, Type *val_type,
|
||||
lbValue *val_, lbValue *key_, lbBlock **loop_, lbBlock **done_) {
|
||||
gb_internal void lb_build_range_map(lbProcedure *p, lbValue expr, Type *val_type,
|
||||
lbValue *val_, lbValue *key_, lbBlock **loop_, lbBlock **done_) {
|
||||
lbModule *m = p->module;
|
||||
|
||||
Type *type = base_type(type_deref(expr.type));
|
||||
@@ -466,8 +456,8 @@ void lb_build_range_map(lbProcedure *p, lbValue expr, Type *val_type,
|
||||
|
||||
|
||||
|
||||
void lb_build_range_string(lbProcedure *p, lbValue expr, Type *val_type,
|
||||
lbValue *val_, lbValue *idx_, lbBlock **loop_, lbBlock **done_) {
|
||||
gb_internal void lb_build_range_string(lbProcedure *p, lbValue expr, Type *val_type,
|
||||
lbValue *val_, lbValue *idx_, lbBlock **loop_, lbBlock **done_) {
|
||||
lbModule *m = p->module;
|
||||
lbValue count = lb_const_int(m, t_int, 0);
|
||||
Type *expr_type = base_type(expr.type);
|
||||
@@ -526,8 +516,8 @@ void lb_build_range_string(lbProcedure *p, lbValue expr, Type *val_type,
|
||||
}
|
||||
|
||||
|
||||
void lb_build_range_interval(lbProcedure *p, AstBinaryExpr *node,
|
||||
AstRangeStmt *rs, Scope *scope) {
|
||||
gb_internal void lb_build_range_interval(lbProcedure *p, AstBinaryExpr *node,
|
||||
AstRangeStmt *rs, Scope *scope) {
|
||||
bool ADD_EXTRA_WRAPPING_CHECK = true;
|
||||
|
||||
lbModule *m = p->module;
|
||||
@@ -630,7 +620,7 @@ void lb_build_range_interval(lbProcedure *p, AstBinaryExpr *node,
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void lb_build_range_tuple(lbProcedure *p, Ast *expr, Type *val0_type, Type *val1_type,
|
||||
lbValue *val0_, lbValue *val1_, lbBlock **loop_, lbBlock **done_) {
|
||||
gb_internal void lb_build_range_tuple(lbProcedure *p, Ast *expr, Type *val0_type, Type *val1_type,
|
||||
lbValue *val0_, lbValue *val1_, lbBlock **loop_, lbBlock **done_) {
|
||||
lbBlock *loop = lb_create_block(p, "for.tuple.loop");
|
||||
lb_emit_jump(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;
|
||||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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) {
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
GB_ASSERT(e != nullptr);
|
||||
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);
|
||||
if (e == nullptr) {
|
||||
return {};
|
||||
@@ -1335,7 +1325,7 @@ lbAddr lb_store_range_stmt_val(lbProcedure *p, Ast *stmt_val, lbValue value) {
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
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) {
|
||||
lbValue value = {};
|
||||
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);
|
||||
}
|
||||
}
|
||||
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;
|
||||
if (t->kind == Type_Tuple) {
|
||||
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) {
|
||||
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);
|
||||
bool return_by_pointer = ft->ret.kind == lbArg_Indirect;
|
||||
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);
|
||||
}
|
||||
}
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
lb_open_scope(p, is->scope); // Scope #1
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
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) {
|
||||
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;
|
||||
defer (p->curr_stmt = prev_stmt);
|
||||
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) {
|
||||
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 i = count;
|
||||
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);
|
||||
GB_ASSERT(pt->kind == Type_Proc);
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
GB_ASSERT(pt->kind == Type_Proc);
|
||||
if (pt->Proc.calling_convention == ProcCC_Odin) {
|
||||
|
||||
@@ -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;
|
||||
isize index = type_info_index(info, type, err_on_not_found);
|
||||
if (index >= 0) {
|
||||
@@ -13,7 +13,7 @@ isize lb_type_info_index(CheckerInfo *info, Type *type, bool err_on_not_found=tr
|
||||
return -1;
|
||||
}
|
||||
|
||||
lbValue lb_typeid(lbModule *m, Type *type) {
|
||||
gb_internal lbValue lb_typeid(lbModule *m, Type *type) {
|
||||
GB_ASSERT(!build_context.disallow_rtti);
|
||||
|
||||
type = default_type(type);
|
||||
@@ -90,7 +90,7 @@ lbValue lb_typeid(lbModule *m, Type *type) {
|
||||
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);
|
||||
|
||||
type = default_type(type);
|
||||
@@ -102,36 +102,36 @@ lbValue lb_type_info(lbModule *m, Type *type) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
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;
|
||||
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);
|
||||
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;
|
||||
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);
|
||||
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;
|
||||
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);
|
||||
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;
|
||||
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);
|
||||
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;
|
||||
@@ -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) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
switch (t->kind) {
|
||||
case Type_Basic:
|
||||
@@ -39,7 +39,7 @@ bool lb_is_type_aggregate(Type *t) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void lb_emit_unreachable(lbProcedure *p) {
|
||||
gb_internal void lb_emit_unreachable(lbProcedure *p) {
|
||||
LLVMValueRef instr = LLVMGetLastInstruction(p->curr_block->block);
|
||||
if (instr == nullptr || !lb_is_instr_terminating(instr)) {
|
||||
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);
|
||||
GB_ASSERT(is_type_integer(src) || is_type_float(src));
|
||||
if (is_type_different_to_arch_endianness(src)) {
|
||||
@@ -57,7 +57,7 @@ lbValue lb_correct_endianness(lbProcedure *p, lbValue 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;
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
lbValue res = {};
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
y = lb_emit_conv(p, y, t);
|
||||
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);
|
||||
y = lb_emit_conv(p, y, t);
|
||||
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 = {};
|
||||
z = lb_emit_max(p, t, x, min);
|
||||
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)) {
|
||||
LLVMValueRef values[2] = {
|
||||
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;
|
||||
if (are_types_identical(t, src_type)) {
|
||||
return value;
|
||||
@@ -259,7 +259,7 @@ lbValue lb_emit_transmute(lbProcedure *p, lbValue value, Type *t) {
|
||||
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);
|
||||
if (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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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 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 = {};
|
||||
if (is_type_boolean(rhs.type)) {
|
||||
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) {
|
||||
return lb_build_expr(p, else_expr);
|
||||
}
|
||||
@@ -435,10 +435,10 @@ lbValue lb_emit_or_else(lbProcedure *p, Ast *arg, Ast *else_expr, TypeAndValue c
|
||||
}
|
||||
}
|
||||
|
||||
void lb_build_return_stmt(lbProcedure *p, Slice<Ast *> const &return_results);
|
||||
void lb_build_return_stmt_internal(lbProcedure *p, lbValue res);
|
||||
gb_internal void lb_build_return_stmt(lbProcedure *p, Slice<Ast *> const &return_results);
|
||||
gb_internal void lb_build_return_stmt_internal(lbProcedure *p, lbValue res);
|
||||
|
||||
lbValue lb_emit_or_return(lbProcedure *p, Ast *arg, TypeAndValue const &tv) {
|
||||
gb_internal lbValue lb_emit_or_return(lbProcedure *p, Ast *arg, TypeAndValue const &tv) {
|
||||
lbValue lhs = {};
|
||||
lbValue 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));
|
||||
Type *type = type_deref(addr.type);
|
||||
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));
|
||||
|
||||
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);
|
||||
|
||||
char const *name = "llvm.ctpop";
|
||||
@@ -539,7 +539,7 @@ lbValue lb_emit_count_ones(lbProcedure *p, lbValue x, Type *type) {
|
||||
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);
|
||||
i64 sz = 8*type_size_of(elem);
|
||||
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);
|
||||
|
||||
char const *name = "llvm.cttz";
|
||||
@@ -566,7 +566,7 @@ lbValue lb_emit_count_trailing_zeros(lbProcedure *p, lbValue x, Type *type) {
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
char const *name = "llvm.bitreverse";
|
||||
@@ -599,15 +599,7 @@ lbValue lb_emit_reverse_bits(lbProcedure *p, lbValue x, Type *type) {
|
||||
}
|
||||
|
||||
|
||||
lbValue lb_emit_bit_set_card(lbProcedure *p, lbValue x) {
|
||||
GB_ASSERT(is_type_bit_set(x.type));
|
||||
Type *underlying = bit_set_to_int(x.type);
|
||||
lbValue card = lb_emit_count_ones(p, x, underlying);
|
||||
return lb_emit_conv(p, card, t_int);
|
||||
}
|
||||
|
||||
|
||||
lbValue lb_emit_union_cast_only_ok_check(lbProcedure *p, lbValue value, Type *type, TokenPos pos) {
|
||||
gb_internal lbValue lb_emit_union_cast_only_ok_check(lbProcedure *p, lbValue value, Type *type, TokenPos pos) {
|
||||
GB_ASSERT(is_type_tuple(type));
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
Type *src_type = value.type;
|
||||
@@ -826,13 +818,13 @@ lbAddr lb_emit_any_cast_addr(lbProcedure *p, lbValue value, Type *type, TokenPos
|
||||
}
|
||||
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));
|
||||
}
|
||||
|
||||
|
||||
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
|
||||
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)) {
|
||||
lbValue res = {};
|
||||
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);
|
||||
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)) {
|
||||
lbValue res = {};
|
||||
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);
|
||||
LLVMTypeRef struct_type = lb_type(m, t);
|
||||
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;
|
||||
}
|
||||
|
||||
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) {
|
||||
auto field_remapping = lb_get_struct_remapping(m, t);
|
||||
index = field_remapping[index];
|
||||
@@ -896,7 +888,7 @@ i32 lb_convert_struct_index(lbModule *m, Type *t, i32 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
|
||||
padding_align = gb_clamp(padding_align, 1, 8);
|
||||
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",
|
||||
"LLVMHalfTypeKind",
|
||||
"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);
|
||||
GB_ASSERT(is_type_tuple(t));
|
||||
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));
|
||||
Type *t = base_type(type_deref(s.type));
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
GB_ASSERT(is_type_tuple(t));
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
if (is_type_tuple(t)) {
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
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 res = lb_emit_deep_field_gep(p, ptr, sel);
|
||||
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;
|
||||
GB_ASSERT_MSG(is_type_pointer(t), "%s", type_to_string(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;
|
||||
}
|
||||
|
||||
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;
|
||||
GB_ASSERT(is_type_pointer(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);
|
||||
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;
|
||||
GB_ASSERT(is_type_pointer(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);
|
||||
}
|
||||
|
||||
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);
|
||||
LLVMValueRef indices[1] = {index.value};
|
||||
lbValue res = {};
|
||||
@@ -1373,7 +1365,7 @@ lbValue lb_emit_ptr_offset(lbProcedure *p, lbValue ptr, lbValue index) {
|
||||
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;
|
||||
GB_ASSERT(is_type_pointer(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);
|
||||
}
|
||||
|
||||
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;
|
||||
GB_ASSERT(is_type_pointer(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);
|
||||
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);
|
||||
GB_ASSERT(is_type_slice(t));
|
||||
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, 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);
|
||||
GB_ASSERT(is_type_string(t));
|
||||
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);
|
||||
}
|
||||
|
||||
lbValue lb_string_elem(lbProcedure *p, lbValue string) {
|
||||
gb_internal lbValue lb_string_elem(lbProcedure *p, lbValue string) {
|
||||
Type *t = base_type(string.type);
|
||||
GB_ASSERT(t->kind == Type_Basic && t->Basic.kind == Basic_string);
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
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));
|
||||
auto args = array_make<lbValue>(permanent_allocator(), 1);
|
||||
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);
|
||||
GB_ASSERT(is_type_array(t));
|
||||
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));
|
||||
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));
|
||||
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));
|
||||
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));
|
||||
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));
|
||||
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));
|
||||
lbValue len = lb_emit_struct_ev(p, value, 1);
|
||||
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;
|
||||
GB_ASSERT(is_type_pointer(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);
|
||||
}
|
||||
|
||||
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));
|
||||
lbValue zero = lb_const_int(p->module, t_uintptr, 0);
|
||||
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);
|
||||
}
|
||||
|
||||
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));
|
||||
lbValue data = lb_emit_struct_ev(p, 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);
|
||||
bool is_ptr = false;
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
for (unsigned i = 0; i < count; i++) {
|
||||
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);
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
@@ -1663,16 +1651,16 @@ LLVMValueRef llvm_mask_zero(lbModule *m, unsigned count) {
|
||||
// #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, "");
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
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);
|
||||
if (LLVMIsConstant(value)) {
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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, "");
|
||||
}
|
||||
|
||||
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);
|
||||
unsigned len = LLVMGetVectorSize(vector_type);
|
||||
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, "");
|
||||
}
|
||||
|
||||
LLVMValueRef llvm_vector_reduce_add(lbProcedure *p, LLVMValueRef value) {
|
||||
gb_internal LLVMValueRef llvm_vector_reduce_add(lbProcedure *p, LLVMValueRef value) {
|
||||
LLVMTypeRef type = LLVMTypeOf(value);
|
||||
GB_ASSERT(LLVMGetTypeKind(type) == LLVMVectorTypeKind);
|
||||
LLVMTypeRef elem = OdinLLVMGetVectorElementType(type);
|
||||
@@ -1810,7 +1798,7 @@ LLVMValueRef llvm_vector_reduce_add(lbProcedure *p, LLVMValueRef value) {
|
||||
#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));
|
||||
|
||||
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, "");
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
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);
|
||||
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,
|
||||
cast(char *)str.text, cast(size_t)str.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()) {
|
||||
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()) {
|
||||
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);
|
||||
if (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);
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
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);
|
||||
lbModule *m = p->module;
|
||||
|
||||
@@ -1964,7 +1952,7 @@ lbValue lb_handle_objc_register_selector(lbProcedure *p, Ast *expr) {
|
||||
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);
|
||||
if (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);
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
if (tav.mode == Addressing_Type) {
|
||||
Type *type = tav.type;
|
||||
@@ -2044,7 +2032,7 @@ lbValue lb_handle_objc_id(lbProcedure *p, Ast *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);
|
||||
|
||||
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);
|
||||
i64 v = exact_value_to_i64(value);
|
||||
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;
|
||||
return llvm_atomic_ordering_from_odin(value);
|
||||
}
|
||||
|
||||
119
src/main.cpp
119
src/main.cpp
@@ -3,25 +3,32 @@
|
||||
#include "common.cpp"
|
||||
#include "timings.cpp"
|
||||
#include "tokenizer.cpp"
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4505)
|
||||
#endif
|
||||
#include "big_int.cpp"
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
#include "exact_value.cpp"
|
||||
#include "build_settings.cpp"
|
||||
|
||||
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 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");
|
||||
}
|
||||
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);
|
||||
}
|
||||
void global_thread_pool_wait(void) {
|
||||
gb_internal void global_thread_pool_wait(void) {
|
||||
thread_pool_wait(&global_thread_pool);
|
||||
}
|
||||
|
||||
|
||||
void debugf(char const *fmt, ...) {
|
||||
gb_internal void debugf(char const *fmt, ...) {
|
||||
if (build_context.show_debug_messages) {
|
||||
gb_printf_err("[DEBUG] ");
|
||||
va_list va;
|
||||
@@ -58,11 +65,10 @@ gb_global Timings global_timings = {0};
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "query_data.cpp"
|
||||
#include "bug_report.cpp"
|
||||
|
||||
// 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
|
||||
char *cmd_line = gb_alloc_array(gb_heap_allocator(), char, cmd_cap);
|
||||
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;
|
||||
Timings *timings = &global_timings;
|
||||
|
||||
@@ -524,7 +530,7 @@ i32 linker_stage(lbGenerator *gen) {
|
||||
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();
|
||||
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
@@ -553,7 +559,7 @@ Array<String> setup_args(int argc, char const **argv) {
|
||||
#endif
|
||||
}
|
||||
|
||||
void print_usage_line(i32 indent, char const *fmt, ...) {
|
||||
gb_internal void print_usage_line(i32 indent, char const *fmt, ...) {
|
||||
while (indent --> 0) {
|
||||
gb_printf_err("\t");
|
||||
}
|
||||
@@ -564,7 +570,7 @@ void print_usage_line(i32 indent, char const *fmt, ...) {
|
||||
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, "Usage:");
|
||||
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, "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, "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, "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");
|
||||
@@ -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};
|
||||
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 = {};
|
||||
|
||||
/*
|
||||
@@ -747,7 +752,7 @@ ExactValue build_param_to_exact_value(String name, String param) {
|
||||
}
|
||||
|
||||
// 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();
|
||||
String name = copy_string(a, flag);
|
||||
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));
|
||||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
@@ -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_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_AllPackages, str_lit("all-packages"), 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;
|
||||
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:
|
||||
build_context.cmd_doc_flags |= CmdDocFlag_Short;
|
||||
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");
|
||||
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;
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
/*
|
||||
@@ -1749,7 +1705,7 @@ void timings_export_all(Timings *t, Checker *c, bool timings_are_finalized = fal
|
||||
gb_printf("Done.\n");
|
||||
}
|
||||
|
||||
void show_timings(Checker *c, Timings *t) {
|
||||
gb_internal void show_timings(Checker *c, Timings *t) {
|
||||
Parser *p = c->parser;
|
||||
isize lines = p->total_line_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;
|
||||
|
||||
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, "Usage:");
|
||||
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.");
|
||||
} else if (command == "test") {
|
||||
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") {
|
||||
print_usage_line(1, "doc generate documentation from a directory of .odin files");
|
||||
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;
|
||||
|
||||
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, "");
|
||||
}
|
||||
|
||||
bool check_env(void) {
|
||||
gb_internal bool check_env(void) {
|
||||
gbAllocator a = heap_allocator();
|
||||
char const *odin_root = gb_get_env("ODIN_ROOT", a);
|
||||
defer (gb_free(a, cast(void *)odin_root));
|
||||
@@ -2348,7 +2302,7 @@ struct StripSemicolonFile {
|
||||
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;
|
||||
gbFileError err = gbFileError_None;
|
||||
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;
|
||||
}
|
||||
|
||||
int strip_semicolons(Parser *parser) {
|
||||
gb_internal int strip_semicolons(Parser *parser) {
|
||||
isize file_count = 0;
|
||||
for_array(i, parser->packages) {
|
||||
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.no_output_files = true;
|
||||
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") {
|
||||
if (args.count < 3) {
|
||||
usage(args[0]);
|
||||
@@ -2824,12 +2769,8 @@ int main(int arg_count, char const **arg_ptr) {
|
||||
print_show_unused(checker);
|
||||
}
|
||||
|
||||
if (build_context.query_data_set_settings.ok) {
|
||||
generate_and_print_query_data(checker, &global_timings);
|
||||
} else {
|
||||
if (build_context.show_timings) {
|
||||
show_timings(checker, &global_timings);
|
||||
}
|
||||
if (build_context.show_timings) {
|
||||
show_timings(checker, &global_timings);
|
||||
}
|
||||
|
||||
if (global_error_collector.count != 0) {
|
||||
|
||||
@@ -58,40 +58,40 @@ struct Find_Result {
|
||||
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));
|
||||
}
|
||||
|
||||
String16 mc_string_to_wstring(String str) {
|
||||
gb_internal String16 mc_string_to_wstring(String 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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
void mc_free(String16 str) {
|
||||
gb_internal void mc_free(String16 str) {
|
||||
if (str.len) gb_free(mc_allocator, str.text);
|
||||
}
|
||||
|
||||
void mc_free_all() {
|
||||
gb_internal void mc_free_all() {
|
||||
gb_free_all(mc_allocator);
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ typedef struct _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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
bool success = !!FindNextFileW(handle, &_find_data);
|
||||
|
||||
@@ -124,7 +124,7 @@ bool mc_find_next(HANDLE handle, MC_Find_Data *find_data) {
|
||||
return success;
|
||||
}
|
||||
|
||||
void mc_find_close(HANDLE handle) {
|
||||
gb_internal void mc_find_close(HANDLE handle) {
|
||||
FindClose(handle);
|
||||
}
|
||||
|
||||
@@ -216,7 +216,7 @@ struct Version_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
|
||||
// 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;
|
||||
}
|
||||
|
||||
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,
|
||||
// get the value stored under the 'version' subkey.
|
||||
// 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;
|
||||
}
|
||||
|
||||
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.
|
||||
|
||||
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;
|
||||
|
||||
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
|
||||
// to fight through Microsoft craziness. The things that the fine
|
||||
// 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
|
||||
// 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) {
|
||||
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
|
||||
// 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.
|
||||
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) {
|
||||
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_windows_kit_paths(&r);
|
||||
find_visual_studio_by_fighting_through_microsoft_craziness(&r);
|
||||
|
||||
571
src/parser.cpp
571
src/parser.cpp
File diff suppressed because it is too large
Load Diff
100
src/parser.hpp
100
src/parser.hpp
@@ -62,15 +62,6 @@ enum PackageKind {
|
||||
Package_Init,
|
||||
};
|
||||
|
||||
struct ImportedPackage {
|
||||
PackageKind kind;
|
||||
String path;
|
||||
String rel_path;
|
||||
TokenPos pos; // import
|
||||
isize index;
|
||||
};
|
||||
|
||||
|
||||
struct ImportedFile {
|
||||
AstPackage *pkg;
|
||||
FileInfo fi;
|
||||
@@ -99,7 +90,11 @@ struct AstFile {
|
||||
Scope * scope;
|
||||
|
||||
Ast * pkg_decl;
|
||||
|
||||
String fullpath;
|
||||
String filename;
|
||||
String directory;
|
||||
|
||||
Tokenizer tokenizer;
|
||||
Array<Token> tokens;
|
||||
isize curr_token_index;
|
||||
@@ -109,6 +104,7 @@ struct AstFile {
|
||||
Token package_token;
|
||||
String package_name;
|
||||
|
||||
|
||||
// >= 0: In Expression
|
||||
// < 0: In Control Clause
|
||||
// NOTE(bill): Used to prevent type literals in control clauses
|
||||
@@ -136,9 +132,8 @@ struct AstFile {
|
||||
CommentGroup *docs; // current docs
|
||||
Array<CommentGroup *> comments; // All the comments!
|
||||
|
||||
// TODO(bill): make this a basic queue as it does not require
|
||||
// any multiple thread capabilities
|
||||
MPMCQueue<Ast *> delayed_decls_queues[AstDelayQueue_COUNT];
|
||||
// This is effectively a queue but does not require any multi-threading capabilities
|
||||
Array<Ast *> delayed_decls_queues[AstDelayQueue_COUNT];
|
||||
|
||||
#define PARSER_MAX_FIX_COUNT 6
|
||||
isize fix_count;
|
||||
@@ -177,6 +172,9 @@ struct AstPackage {
|
||||
bool is_single_file;
|
||||
isize order;
|
||||
|
||||
BlockingMutex files_mutex;
|
||||
BlockingMutex foreign_files_mutex;
|
||||
|
||||
MPMCQueue<AstPackageExportedEntity> exported_entity_queue;
|
||||
|
||||
// NOTE(bill): Created/set in checker
|
||||
@@ -186,20 +184,33 @@ struct AstPackage {
|
||||
};
|
||||
|
||||
|
||||
struct ParseFileErrorNode {
|
||||
ParseFileErrorNode *next, *prev;
|
||||
ParseFileError err;
|
||||
};
|
||||
|
||||
struct Parser {
|
||||
String init_fullpath;
|
||||
StringSet imported_files; // fullpath
|
||||
Array<AstPackage *> packages;
|
||||
Array<ImportedPackage> package_imports;
|
||||
isize file_to_process_count;
|
||||
isize total_token_count;
|
||||
isize total_line_count;
|
||||
BlockingMutex wait_mutex;
|
||||
BlockingMutex import_mutex;
|
||||
BlockingMutex file_add_mutex;
|
||||
BlockingMutex file_decl_mutex;
|
||||
BlockingMutex packages_mutex;
|
||||
MPMCQueue<ParseFileError> file_error_queue;
|
||||
String init_fullpath;
|
||||
|
||||
StringSet imported_files; // fullpath
|
||||
BlockingMutex imported_files_mutex;
|
||||
|
||||
Array<AstPackage *> packages;
|
||||
BlockingMutex packages_mutex;
|
||||
|
||||
std::atomic<isize> file_to_process_count;
|
||||
std::atomic<isize> total_token_count;
|
||||
std::atomic<isize> total_line_count;
|
||||
|
||||
// TODO(bill): What should this mutex be per?
|
||||
// * Parser
|
||||
// * Package
|
||||
// * File
|
||||
BlockingMutex file_decl_mutex;
|
||||
|
||||
BlockingMutex file_error_mutex;
|
||||
ParseFileErrorNode * file_error_head;
|
||||
ParseFileErrorNode * file_error_tail;
|
||||
};
|
||||
|
||||
struct ParserWorkerData {
|
||||
@@ -258,7 +269,7 @@ enum ProcCallingConvention : i32 {
|
||||
ProcCC_ForeignBlockDefault = -1,
|
||||
};
|
||||
|
||||
char const *proc_calling_convention_strings[ProcCC_MAX] = {
|
||||
gb_global char const *proc_calling_convention_strings[ProcCC_MAX] = {
|
||||
"",
|
||||
"odin",
|
||||
"contextless",
|
||||
@@ -272,7 +283,7 @@ char const *proc_calling_convention_strings[ProcCC_MAX] = {
|
||||
"sysv",
|
||||
};
|
||||
|
||||
ProcCallingConvention default_calling_convention(void) {
|
||||
gb_internal ProcCallingConvention default_calling_convention(void) {
|
||||
return ProcCC_Odin;
|
||||
}
|
||||
|
||||
@@ -332,7 +343,7 @@ enum InlineAsmDialectKind : u8 {
|
||||
InlineAsmDialect_COUNT,
|
||||
};
|
||||
|
||||
char const *inline_asm_dialect_strings[InlineAsmDialect_COUNT] = {
|
||||
gb_global char const *inline_asm_dialect_strings[InlineAsmDialect_COUNT] = {
|
||||
"",
|
||||
"att",
|
||||
"intel",
|
||||
@@ -457,11 +468,6 @@ AST_KIND(_StmtBegin, "", bool) \
|
||||
AST_KIND(BadStmt, "bad statement", struct { Token begin, end; }) \
|
||||
AST_KIND(EmptyStmt, "empty statement", struct { Token token; }) \
|
||||
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 { \
|
||||
Token op; \
|
||||
Slice<Ast *> lhs, rhs; \
|
||||
@@ -729,7 +735,7 @@ enum AstKind : u16 {
|
||||
Ast_COUNT,
|
||||
};
|
||||
|
||||
String const ast_strings[] = {
|
||||
gb_global String const ast_strings[] = {
|
||||
{cast(u8 *)"invalid node", gb_size_of("invalid node")},
|
||||
#define AST_KIND(_kind_name_, name, ...) {cast(u8 *)name, gb_size_of(name)-1},
|
||||
AST_KINDS
|
||||
@@ -742,7 +748,7 @@ String const ast_strings[] = {
|
||||
#undef AST_KIND
|
||||
|
||||
|
||||
isize const ast_variant_sizes[] = {
|
||||
gb_global isize const ast_variant_sizes[] = {
|
||||
0,
|
||||
#define AST_KIND(_kind_name_, name, ...) gb_size_of(GB_JOIN2(Ast, _kind_name_)),
|
||||
AST_KINDS
|
||||
@@ -754,7 +760,7 @@ struct AstCommonStuff {
|
||||
u8 state_flags;
|
||||
u8 viral_state_flags;
|
||||
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 {
|
||||
@@ -762,7 +768,7 @@ struct Ast {
|
||||
u8 state_flags;
|
||||
u8 viral_state_flags;
|
||||
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
|
||||
union {
|
||||
@@ -793,33 +799,33 @@ struct Ast {
|
||||
#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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
return arena_allocator(arena);
|
||||
}
|
||||
|
||||
Ast *alloc_ast_node(AstFile *f, AstKind kind);
|
||||
gb_internal Ast *alloc_ast_node(AstFile *f, AstKind kind);
|
||||
|
||||
gbString expr_to_string(Ast *expression);
|
||||
bool allow_field_separator(AstFile *f);
|
||||
gb_internal gbString expr_to_string(Ast *expression);
|
||||
gb_internal bool allow_field_separator(AstFile *f);
|
||||
@@ -1,4 +1,4 @@
|
||||
Token ast_token(Ast *node) {
|
||||
gb_internal Token ast_token(Ast *node) {
|
||||
switch (node->kind) {
|
||||
case Ast_Ident: return node->Ident.token;
|
||||
case Ast_Implicit: return node->Implicit;
|
||||
@@ -53,7 +53,6 @@ Token ast_token(Ast *node) {
|
||||
case Ast_BadStmt: return node->BadStmt.begin;
|
||||
case Ast_EmptyStmt: return node->EmptyStmt.token;
|
||||
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_BlockStmt: return node->BlockStmt.open;
|
||||
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_EmptyStmt: return node->EmptyStmt.token;
|
||||
case Ast_ExprStmt: return ast_end_token(node->ExprStmt.expr);
|
||||
case Ast_TagStmt: return ast_end_token(node->TagStmt.stmt);
|
||||
case Ast_AssignStmt:
|
||||
if (node->AssignStmt.rhs.count > 0) {
|
||||
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;
|
||||
}
|
||||
|
||||
TokenPos ast_end_pos(Ast *node) {
|
||||
gb_internal TokenPos ast_end_pos(Ast *node) {
|
||||
return token_pos_end(ast_end_token(node));
|
||||
}
|
||||
|
||||
30
src/path.cpp
30
src/path.cpp
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
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--) {
|
||||
if (s[i] == '.') {
|
||||
return substring(s, 0, i);
|
||||
@@ -10,7 +10,7 @@ String remove_extension_from_path(String const &s) {
|
||||
return s;
|
||||
}
|
||||
|
||||
String remove_directory_from_path(String const &s) {
|
||||
gb_internal String remove_directory_from_path(String const &s) {
|
||||
isize len = 0;
|
||||
for (isize i = s.len-1; i >= 0; i--) {
|
||||
if (s[i] == '/' ||
|
||||
@@ -22,9 +22,9 @@ String remove_directory_from_path(String const &s) {
|
||||
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)) {
|
||||
return s;
|
||||
}
|
||||
@@ -43,7 +43,7 @@ String directory_from_path(String const &s) {
|
||||
}
|
||||
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
bool path_is_directory(String path) {
|
||||
gb_internal bool path_is_directory(String path) {
|
||||
gbAllocator a = heap_allocator();
|
||||
String16 wstr = string_to_string16(a, path);
|
||||
defer (gb_free(a, wstr.text));
|
||||
@@ -55,7 +55,7 @@ String directory_from_path(String const &s) {
|
||||
}
|
||||
|
||||
#else
|
||||
bool path_is_directory(String path) {
|
||||
gb_internal bool path_is_directory(String path) {
|
||||
gbAllocator a = heap_allocator();
|
||||
char *copy = cast(char *)copy_string(a, path).text;
|
||||
defer (gb_free(a, copy));
|
||||
@@ -69,7 +69,7 @@ String directory_from_path(String const &s) {
|
||||
#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();
|
||||
char *path_c = gb_alloc_str_len(ha, cast(char *)path.text, path.len);
|
||||
defer (gb_free(ha, path_c));
|
||||
@@ -93,7 +93,7 @@ struct Path {
|
||||
};
|
||||
|
||||
// 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) {
|
||||
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`.
|
||||
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);
|
||||
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,
|
||||
// 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 = {};
|
||||
|
||||
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.
|
||||
String last_path_element(String const &path) {
|
||||
gb_internal String last_path_element(String const &path) {
|
||||
isize count = 0;
|
||||
u8 * start = (u8 *)(&path.text[path.len - 1]);
|
||||
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("");
|
||||
}
|
||||
|
||||
bool path_is_directory(Path path) {
|
||||
gb_internal bool path_is_directory(Path path) {
|
||||
String path_string = path_to_full_path(heap_allocator(), path);
|
||||
defer (gb_free(heap_allocator(), path_string.text));
|
||||
|
||||
@@ -204,7 +204,7 @@ enum ReadDirectoryError {
|
||||
ReadDirectory_COUNT,
|
||||
};
|
||||
|
||||
i64 get_file_size(String path) {
|
||||
gb_internal i64 get_file_size(String path) {
|
||||
char *c_str = alloc_cstring(heap_allocator(), path);
|
||||
defer (gb_free(heap_allocator(), c_str));
|
||||
|
||||
@@ -219,7 +219,7 @@ i64 get_file_size(String path) {
|
||||
|
||||
|
||||
#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);
|
||||
|
||||
gbAllocator a = heap_allocator();
|
||||
@@ -314,7 +314,7 @@ ReadDirectoryError read_directory(String path, Array<FileInfo> *fi) {
|
||||
|
||||
#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);
|
||||
|
||||
gbAllocator a = heap_allocator();
|
||||
|
||||
@@ -7,7 +7,7 @@ struct PriorityQueue {
|
||||
};
|
||||
|
||||
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)
|
||||
isize i = i0;
|
||||
isize j, j1, j2;
|
||||
@@ -29,7 +29,7 @@ bool priority_queue_shift_down(PriorityQueue<T> *pq, isize i0, isize n) {
|
||||
}
|
||||
|
||||
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) {
|
||||
isize i = (j-1)/2;
|
||||
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
|
||||
// the heap ordering. This using a basic "heapsort" with shift up and a shift down parts.
|
||||
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)) {
|
||||
priority_queue_shift_up(pq, i);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
priority_queue_shift_up(pq, pq->queue.count-1);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
isize n = pq->queue.count - 1;
|
||||
@@ -67,7 +67,7 @@ T priority_queue_pop(PriorityQueue<T> *pq) {
|
||||
|
||||
|
||||
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);
|
||||
isize n = pq->queue.count - 1;
|
||||
if (n != i) {
|
||||
@@ -80,7 +80,7 @@ T priority_queue_remove(PriorityQueue<T> *pq, isize i) {
|
||||
|
||||
|
||||
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),
|
||||
void (* swap)(T *q, isize i, isize j)) {
|
||||
PriorityQueue<T> pq = {};
|
||||
|
||||
@@ -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)
|
||||
key = (~key) + (key << 21);
|
||||
key = key ^ (key >> 24);
|
||||
@@ -41,35 +41,35 @@ u32 ptr_map_hash_key(uintptr key) {
|
||||
return (word >> 22u) ^ word;
|
||||
#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);
|
||||
}
|
||||
|
||||
|
||||
template <typename K, typename V> void map_init (PtrMap<K, V> *h, gbAllocator a, isize capacity = 16);
|
||||
template <typename K, typename V> void map_destroy (PtrMap<K, V> *h);
|
||||
template <typename K, typename V> V * map_get (PtrMap<K, V> *h, K key);
|
||||
template <typename K, typename V> void map_set (PtrMap<K, V> *h, K key, V const &value);
|
||||
template <typename K, typename V> void map_remove (PtrMap<K, V> *h, K key);
|
||||
template <typename K, typename V> void map_clear (PtrMap<K, V> *h);
|
||||
template <typename K, typename V> void map_grow (PtrMap<K, V> *h);
|
||||
template <typename K, typename V> void map_rehash (PtrMap<K, V> *h, isize new_count);
|
||||
template <typename K, typename V> void map_reserve (PtrMap<K, V> *h, isize cap);
|
||||
template <typename K, typename V> gb_internal void map_init (PtrMap<K, V> *h, gbAllocator a, isize capacity = 16);
|
||||
template <typename K, typename V> gb_internal void map_destroy (PtrMap<K, V> *h);
|
||||
template <typename K, typename V> gb_internal V * map_get (PtrMap<K, V> *h, K key);
|
||||
template <typename K, typename V> gb_internal void map_set (PtrMap<K, V> *h, K key, V const &value);
|
||||
template <typename K, typename V> gb_internal void map_remove (PtrMap<K, V> *h, K key);
|
||||
template <typename K, typename V> gb_internal void map_clear (PtrMap<K, V> *h);
|
||||
template <typename K, typename V> gb_internal void map_grow (PtrMap<K, V> *h);
|
||||
template <typename K, typename V> gb_internal void map_rehash (PtrMap<K, V> *h, isize new_count);
|
||||
template <typename K, typename V> gb_internal void map_reserve (PtrMap<K, V> *h, isize cap);
|
||||
|
||||
#if PTR_MAP_ENABLE_MULTI_MAP
|
||||
// Mutlivalued map procedure
|
||||
template <typename K, typename V> PtrMapEntry<K, V> * multi_map_find_first(PtrMap<K, V> *h, K key);
|
||||
template <typename K, typename V> PtrMapEntry<K, V> * multi_map_find_next (PtrMap<K, V> *h, PtrMapEntry<K, V> *e);
|
||||
template <typename K, typename V> gb_internal PtrMapEntry<K, V> * multi_map_find_first(PtrMap<K, V> *h, K key);
|
||||
template <typename K, typename V> gb_internal PtrMapEntry<K, V> * multi_map_find_next (PtrMap<K, V> *h, PtrMapEntry<K, V> *e);
|
||||
|
||||
template <typename K, typename V> isize multi_map_count (PtrMap<K, V> *h, K key);
|
||||
template <typename K, typename V> void multi_map_get_all (PtrMap<K, V> *h, K key, V *items);
|
||||
template <typename K, typename V> void multi_map_insert (PtrMap<K, V> *h, K key, V const &value);
|
||||
template <typename K, typename V> void multi_map_remove (PtrMap<K, V> *h, K key, PtrMapEntry<K, V> *e);
|
||||
template <typename K, typename V> void multi_map_remove_all(PtrMap<K, V> *h, K key);
|
||||
template <typename K, typename V> gb_internal isize multi_map_count (PtrMap<K, V> *h, K key);
|
||||
template <typename K, typename V> gb_internal void multi_map_get_all (PtrMap<K, V> *h, K key, V *items);
|
||||
template <typename K, typename V> gb_internal void multi_map_insert (PtrMap<K, V> *h, K key, V const &value);
|
||||
template <typename K, typename V> gb_internal void multi_map_remove (PtrMap<K, V> *h, K key, PtrMapEntry<K, V> *e);
|
||||
template <typename K, typename V> gb_internal void multi_map_remove_all(PtrMap<K, V> *h, K key);
|
||||
#endif
|
||||
|
||||
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);
|
||||
slice_init(&h->hashes, a, 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>
|
||||
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);
|
||||
array_free(&h->entries);
|
||||
}
|
||||
@@ -137,13 +137,13 @@ gb_internal b32 map__full(PtrMap<K, V> *h) {
|
||||
}
|
||||
|
||||
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);
|
||||
map_rehash(h, new_count);
|
||||
}
|
||||
|
||||
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++) {
|
||||
h->hashes.data[i] = MAP_SENTINEL;
|
||||
}
|
||||
@@ -161,7 +161,7 @@ void map_reset_entries(PtrMap<K, V> *h) {
|
||||
}
|
||||
|
||||
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);
|
||||
if (h->entries.count*2 < h->hashes.count) {
|
||||
return;
|
||||
@@ -172,12 +172,12 @@ void map_reserve(PtrMap<K, V> *h, isize cap) {
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
if (index != MAP_SENTINEL) {
|
||||
return &h->entries.data[index].value;
|
||||
@@ -186,14 +186,14 @@ V *map_get(PtrMap<K, V> *h, K key) {
|
||||
}
|
||||
|
||||
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;
|
||||
GB_ASSERT(index != MAP_SENTINEL);
|
||||
return h->entries.data[index].value;
|
||||
}
|
||||
|
||||
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;
|
||||
MapFindResult fr;
|
||||
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>
|
||||
void map__erase(PtrMap<K, V> *h, MapFindResult const &fr) {
|
||||
gb_internal void map__erase(PtrMap<K, V> *h, MapFindResult const &fr) {
|
||||
MapFindResult last;
|
||||
if (fr.entry_prev == MAP_SENTINEL) {
|
||||
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>
|
||||
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);
|
||||
if (fr.entry_index != MAP_SENTINEL) {
|
||||
map__erase(h, fr);
|
||||
@@ -250,7 +250,7 @@ void map_remove(PtrMap<K, V> *h, K key) {
|
||||
}
|
||||
|
||||
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);
|
||||
for (isize i = 0; i < h->hashes.count; i++) {
|
||||
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
|
||||
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;
|
||||
if (i == MAP_SENTINEL) {
|
||||
return nullptr;
|
||||
@@ -269,7 +269,7 @@ 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) {
|
||||
gb_internal PtrMapEntry<K, V> *multi_map_find_next(PtrMap<K, V> *h, PtrMapEntry<K, V> *e) {
|
||||
MapIndex i = e->next;
|
||||
while (i != MAP_SENTINEL) {
|
||||
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>
|
||||
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;
|
||||
PtrMapEntry<K, V> *e = multi_map_find_first(h, key);
|
||||
while (e != nullptr) {
|
||||
@@ -292,7 +292,7 @@ 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) {
|
||||
gb_internal void multi_map_get_all(PtrMap<K, V> *h, K key, V *items) {
|
||||
isize i = 0;
|
||||
PtrMapEntry<K, V> *e = multi_map_find_first(h, key);
|
||||
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>
|
||||
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;
|
||||
MapIndex i;
|
||||
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>
|
||||
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);
|
||||
if (fr.entry_index != MAP_SENTINEL) {
|
||||
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>
|
||||
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) {
|
||||
map_remove(h, key);
|
||||
}
|
||||
}
|
||||
#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;
|
||||
}
|
||||
|
||||
@@ -10,20 +10,20 @@ struct PtrSet {
|
||||
Array<PtrSetEntry<T>> entries;
|
||||
};
|
||||
|
||||
template <typename T> void ptr_set_init (PtrSet<T> *s, gbAllocator a, isize capacity = 16);
|
||||
template <typename T> void ptr_set_destroy(PtrSet<T> *s);
|
||||
template <typename T> T ptr_set_add (PtrSet<T> *s, T ptr);
|
||||
template <typename T> bool ptr_set_update (PtrSet<T> *s, T ptr); // returns true if it previously existed
|
||||
template <typename T> bool ptr_set_exists (PtrSet<T> *s, T ptr);
|
||||
template <typename T> void ptr_set_remove (PtrSet<T> *s, T ptr);
|
||||
template <typename T> void ptr_set_clear (PtrSet<T> *s);
|
||||
template <typename T> void ptr_set_grow (PtrSet<T> *s);
|
||||
template <typename T> void ptr_set_rehash (PtrSet<T> *s, isize new_count);
|
||||
template <typename T> void ptr_set_reserve(PtrSet<T> *h, isize cap);
|
||||
template <typename T> gb_internal void ptr_set_init (PtrSet<T> *s, gbAllocator a, isize capacity = 16);
|
||||
template <typename T> gb_internal void ptr_set_destroy(PtrSet<T> *s);
|
||||
template <typename T> gb_internal T ptr_set_add (PtrSet<T> *s, T ptr);
|
||||
template <typename T> gb_internal bool ptr_set_update (PtrSet<T> *s, T ptr); // returns true if it previously existed
|
||||
template <typename T> gb_internal bool ptr_set_exists (PtrSet<T> *s, T ptr);
|
||||
template <typename T> gb_internal void ptr_set_remove (PtrSet<T> *s, T ptr);
|
||||
template <typename T> gb_internal void ptr_set_clear (PtrSet<T> *s);
|
||||
template <typename T> gb_internal void ptr_set_grow (PtrSet<T> *s);
|
||||
template <typename T> gb_internal void ptr_set_rehash (PtrSet<T> *s, isize new_count);
|
||||
template <typename T> gb_internal void ptr_set_reserve(PtrSet<T> *h, isize cap);
|
||||
|
||||
|
||||
template <typename T>
|
||||
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) {
|
||||
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>
|
||||
void ptr_set_destroy(PtrSet<T> *s) {
|
||||
gb_internal void ptr_set_destroy(PtrSet<T> *s) {
|
||||
slice_free(&s->hashes, s->entries.allocator);
|
||||
array_free(&s->entries);
|
||||
}
|
||||
@@ -93,13 +93,13 @@ gb_internal bool ptr_set__full(PtrSet<T> *s) {
|
||||
}
|
||||
|
||||
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);
|
||||
ptr_set_rehash(s, new_count);
|
||||
}
|
||||
|
||||
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++) {
|
||||
s->hashes.data[i] = MAP_SENTINEL;
|
||||
}
|
||||
@@ -117,7 +117,7 @@ void ptr_set_reset_entries(PtrSet<T> *s) {
|
||||
}
|
||||
|
||||
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);
|
||||
if (s->entries.count*2 < s->hashes.count) {
|
||||
return;
|
||||
@@ -128,18 +128,18 @@ void ptr_set_reserve(PtrSet<T> *s, isize cap) {
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
return index != MAP_SENTINEL;
|
||||
}
|
||||
|
||||
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;
|
||||
if (index != MAP_SENTINEL) {
|
||||
return index;
|
||||
@@ -149,7 +149,7 @@ gb_inline isize ptr_entry_index(PtrSet<T> *s, T ptr) {
|
||||
|
||||
// Returns true if it already exists
|
||||
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;
|
||||
MapFindResult fr;
|
||||
if (s->hashes.count == 0) {
|
||||
@@ -171,7 +171,7 @@ 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 existsed
|
||||
gb_internal bool ptr_set_update(PtrSet<T> *s, T ptr) { // returns true if it previously existsed
|
||||
bool exists = false;
|
||||
MapIndex index;
|
||||
MapFindResult fr;
|
||||
@@ -198,7 +198,7 @@ bool ptr_set_update(PtrSet<T> *s, T ptr) { // returns true if it previously exis
|
||||
|
||||
|
||||
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;
|
||||
if (fr.entry_prev == MAP_SENTINEL) {
|
||||
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>
|
||||
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);
|
||||
if (fr.entry_index != MAP_SENTINEL) {
|
||||
ptr_set__erase(s, fr);
|
||||
@@ -227,9 +227,30 @@ void ptr_set_remove(PtrSet<T> *s, T ptr) {
|
||||
}
|
||||
|
||||
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);
|
||||
for (isize i = 0; i < s->hashes.count; i++) {
|
||||
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
src/query_data.cpp
1030
src/query_data.cpp
File diff suppressed because it is too large
Load Diff
@@ -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(size % 8 == 0);
|
||||
|
||||
@@ -43,7 +43,7 @@ void mpmc_internal_init_indices(MPMCQueueAtomicIdx *indices, i32 offset, i32 siz
|
||||
|
||||
|
||||
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) {
|
||||
size_i = 8;
|
||||
}
|
||||
@@ -64,7 +64,7 @@ void mpmc_init(MPMCQueue<T> *q, gbAllocator a, isize size_i) {
|
||||
|
||||
|
||||
template <typename T>
|
||||
void mpmc_destroy(MPMCQueue<T> *q) {
|
||||
gb_internal void mpmc_destroy(MPMCQueue<T> *q) {
|
||||
mutex_destroy(&q->mutex);
|
||||
gb_free(q->allocator, q->nodes);
|
||||
gb_free(q->allocator, q->indices);
|
||||
@@ -72,7 +72,7 @@ void mpmc_destroy(MPMCQueue<T> *q) {
|
||||
|
||||
|
||||
template <typename T>
|
||||
bool mpmc_internal_grow(MPMCQueue<T> *q) {
|
||||
gb_internal bool mpmc_internal_grow(MPMCQueue<T> *q) {
|
||||
mutex_lock(&q->mutex);
|
||||
i32 old_size = q->mask+1;
|
||||
i32 new_size = old_size*2;
|
||||
@@ -95,7 +95,7 @@ bool mpmc_internal_grow(MPMCQueue<T> *q) {
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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>
|
||||
bool mpmc_dequeue(MPMCQueue<T> *q, T *data_) {
|
||||
gb_internal bool mpmc_dequeue(MPMCQueue<T> *q, T *data_) {
|
||||
if (q->mask == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -10,17 +10,17 @@ struct RangeCache {
|
||||
};
|
||||
|
||||
|
||||
RangeCache range_cache_make(gbAllocator a) {
|
||||
gb_internal RangeCache range_cache_make(gbAllocator a) {
|
||||
RangeCache cache = {};
|
||||
array_init(&cache.ranges, a);
|
||||
return cache;
|
||||
}
|
||||
|
||||
void range_cache_destroy(RangeCache *c) {
|
||||
gb_internal void range_cache_destroy(RangeCache *c) {
|
||||
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) {
|
||||
RangeValue v = c->ranges[i];
|
||||
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);
|
||||
for_array(i, c->ranges) {
|
||||
RangeValue v = c->ranges[i];
|
||||
@@ -59,12 +59,12 @@ bool range_cache_add_range(RangeCache *c, i64 lo, i64 hi) {
|
||||
}
|
||||
|
||||
|
||||
bool range_cache_index_exists(RangeCache *c, i64 index) {
|
||||
for_array(i, c->ranges) {
|
||||
RangeValue v = c->ranges[i];
|
||||
if (v.lo <= index && index <= v.hi) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// gb_internal bool range_cache_index_exists(RangeCache *c, i64 index) {
|
||||
// for_array(i, c->ranges) {
|
||||
// RangeValue v = c->ranges[i];
|
||||
// if (v.lo <= index && index <= v.hi) {
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
// return false;
|
||||
// }
|
||||
|
||||
128
src/string.cpp
128
src/string.cpp
@@ -1,6 +1,6 @@
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
s.text = cast(u8 *)text;
|
||||
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;
|
||||
s.text = cast(wchar_t *)text;
|
||||
s.len = len;
|
||||
return s;
|
||||
}
|
||||
|
||||
isize string16_len(wchar_t const *s) {
|
||||
gb_internal isize string16_len(wchar_t const *s) {
|
||||
if (s == nullptr) {
|
||||
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));
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
String substring(String const &s, isize lo, isize hi) {
|
||||
gb_internal String substring(String const &s, isize lo, isize hi) {
|
||||
isize max = s.len;
|
||||
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);
|
||||
gb_memmove(c_str, s.text, s.len);
|
||||
c_str[s.len] = '\0';
|
||||
return c_str;
|
||||
}
|
||||
|
||||
char *cstring_duplicate(gbAllocator a, char const *s) {
|
||||
isize len = gb_strlen(s);
|
||||
char *c_str = gb_alloc_array(a, char, len+1);
|
||||
gb_memmove(c_str, s, len);
|
||||
c_str[len] = '\0';
|
||||
return c_str;
|
||||
}
|
||||
|
||||
|
||||
|
||||
gb_inline bool str_eq_ignore_case(String const &a, String const &b) {
|
||||
gb_internal gb_inline bool str_eq_ignore_case(String const &a, String const &b) {
|
||||
if (a.len == b.len) {
|
||||
for (isize i = 0; i < a.len; 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;
|
||||
}
|
||||
|
||||
void string_to_lower(String *s) {
|
||||
gb_internal void string_to_lower(String *s) {
|
||||
for (isize i = 0; i < s->len; 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) {
|
||||
isize n, fast, offset, curr_block;
|
||||
isize *la, *lb;
|
||||
@@ -157,7 +149,7 @@ int string_compare(String const &x, String const &y) {
|
||||
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++) {
|
||||
if (s.text[i] == x) {
|
||||
return i;
|
||||
@@ -166,37 +158,31 @@ isize string_index_byte(String const &s, u8 x) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
GB_COMPARE_PROC(string_cmp_proc) {
|
||||
String x = *(String *)a;
|
||||
String y = *(String *)b;
|
||||
return string_compare(x, y);
|
||||
}
|
||||
|
||||
gb_inline bool str_eq(String const &a, String const &b) {
|
||||
gb_internal gb_inline bool str_eq(String const &a, String const &b) {
|
||||
if (a.len != b.len) return false;
|
||||
return memcmp(a.text, b.text, a.len) == 0;
|
||||
}
|
||||
gb_inline bool str_ne(String const &a, String const &b) { return !str_eq(a, b); }
|
||||
gb_inline bool str_lt(String const &a, String const &b) { return string_compare(a, b) < 0; }
|
||||
gb_inline bool str_gt(String const &a, String const &b) { return string_compare(a, b) > 0; }
|
||||
gb_inline bool str_le(String const &a, String const &b) { return string_compare(a, b) <= 0; }
|
||||
gb_inline bool str_ge(String const &a, String const &b) { return string_compare(a, b) >= 0; }
|
||||
gb_internal gb_inline bool str_ne(String const &a, String const &b) { return !str_eq(a, b); }
|
||||
gb_internal gb_inline bool str_lt(String const &a, String const &b) { return string_compare(a, b) < 0; }
|
||||
gb_internal gb_inline bool str_gt(String const &a, String const &b) { return string_compare(a, b) > 0; }
|
||||
gb_internal gb_inline bool str_le(String const &a, String const &b) { return string_compare(a, b) <= 0; }
|
||||
gb_internal gb_inline bool str_ge(String const &a, String const &b) { return string_compare(a, b) >= 0; }
|
||||
|
||||
gb_inline bool operator == (String const &a, String const &b) { return str_eq(a, b); }
|
||||
gb_inline bool operator != (String const &a, String const &b) { return str_ne(a, b); }
|
||||
gb_inline bool operator < (String const &a, String const &b) { return str_lt(a, b); }
|
||||
gb_inline bool operator > (String const &a, String const &b) { return str_gt(a, b); }
|
||||
gb_inline bool operator <= (String const &a, String const &b) { return str_le(a, b); }
|
||||
gb_inline bool operator >= (String const &a, String const &b) { return str_ge(a, b); }
|
||||
gb_internal gb_inline bool operator == (String const &a, String const &b) { return str_eq(a, b); }
|
||||
gb_internal gb_inline bool operator != (String const &a, String const &b) { return str_ne(a, b); }
|
||||
gb_internal gb_inline bool operator < (String const &a, String const &b) { return str_lt(a, b); }
|
||||
gb_internal gb_inline bool operator > (String const &a, String const &b) { return str_gt(a, b); }
|
||||
gb_internal gb_inline bool operator <= (String const &a, String const &b) { return str_le(a, b); }
|
||||
gb_internal gb_inline bool operator >= (String const &a, String const &b) { return str_ge(a, b); }
|
||||
|
||||
template <isize N> bool operator == (String const &a, char const (&b)[N]) { return str_eq(a, make_string(cast(u8 *)b, N-1)); }
|
||||
template <isize N> bool operator != (String const &a, char const (&b)[N]) { return str_ne(a, make_string(cast(u8 *)b, N-1)); }
|
||||
template <isize N> bool operator < (String const &a, char const (&b)[N]) { return str_lt(a, make_string(cast(u8 *)b, N-1)); }
|
||||
template <isize N> bool operator > (String const &a, char const (&b)[N]) { return str_gt(a, make_string(cast(u8 *)b, N-1)); }
|
||||
template <isize N> bool operator <= (String const &a, char const (&b)[N]) { return str_le(a, make_string(cast(u8 *)b, N-1)); }
|
||||
template <isize N> bool operator >= (String const &a, char const (&b)[N]) { return str_ge(a, make_string(cast(u8 *)b, N-1)); }
|
||||
template <isize N> gb_internal bool operator == (String const &a, char const (&b)[N]) { return str_eq(a, make_string(cast(u8 *)b, N-1)); }
|
||||
template <isize N> gb_internal bool operator != (String const &a, char const (&b)[N]) { return str_ne(a, make_string(cast(u8 *)b, N-1)); }
|
||||
template <isize N> gb_internal bool operator < (String const &a, char const (&b)[N]) { return str_lt(a, make_string(cast(u8 *)b, N-1)); }
|
||||
template <isize N> gb_internal bool operator > (String const &a, char const (&b)[N]) { return str_gt(a, make_string(cast(u8 *)b, N-1)); }
|
||||
template <isize N> gb_internal bool operator <= (String const &a, char const (&b)[N]) { return str_le(a, make_string(cast(u8 *)b, N-1)); }
|
||||
template <isize N> gb_internal bool operator >= (String const &a, char const (&b)[N]) { return str_ge(a, make_string(cast(u8 *)b, N-1)); }
|
||||
|
||||
gb_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) {
|
||||
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;
|
||||
}
|
||||
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
|
||||
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) {
|
||||
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) {
|
||||
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)) {
|
||||
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 i = str.len;
|
||||
while (i --> 0) {
|
||||
@@ -254,7 +240,7 @@ gb_inline isize string_extension_position(String const &str) {
|
||||
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);
|
||||
if (pos < 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);
|
||||
}
|
||||
|
||||
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])) {
|
||||
str.len--;
|
||||
}
|
||||
@@ -279,7 +265,7 @@ String string_trim_whitespace(String 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;
|
||||
for (i = 0; i < s.len; i++) {
|
||||
if (s[i] == c)
|
||||
@@ -288,7 +274,7 @@ bool string_contains_char(String const &s, u8 c) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String filename_from_path(String s) {
|
||||
gb_internal String filename_from_path(String s) {
|
||||
isize i = string_extension_position(s);
|
||||
if (i >= 0) {
|
||||
s = substring(s, 0, i);
|
||||
@@ -307,7 +293,7 @@ String filename_from_path(String s) {
|
||||
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;
|
||||
u8 *data = gb_alloc_array(a, u8, len+1);
|
||||
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;
|
||||
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;
|
||||
u8 *data = gb_alloc_array(a, u8, len+1);
|
||||
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;
|
||||
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;
|
||||
u8 *data = gb_alloc_array(a, u8, len+1);
|
||||
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);
|
||||
}
|
||||
|
||||
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) {
|
||||
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));
|
||||
}
|
||||
|
||||
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);
|
||||
gb_memmove(data, s.text, s.len);
|
||||
data[s.len] = 0;
|
||||
@@ -367,17 +353,17 @@ String copy_string(gbAllocator a, String const &s) {
|
||||
|
||||
|
||||
#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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
#elif defined(GB_SYSTEM_UNIX) || defined(GB_SYSTEM_OSX)
|
||||
|
||||
#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");
|
||||
size_t result = iconv(conv, cast(char **)&multibyte_input, &input_length, cast(char **)&output, &output_size);
|
||||
iconv_close(conv);
|
||||
@@ -385,7 +371,7 @@ String copy_string(gbAllocator a, String const &s) {
|
||||
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");
|
||||
size_t result = iconv(conv, cast(char**) &widechar_input, &input_length, cast(char **)&output, &output_size);
|
||||
iconv_close(conv);
|
||||
@@ -400,7 +386,7 @@ String copy_string(gbAllocator a, String const &s) {
|
||||
|
||||
|
||||
// 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;
|
||||
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;
|
||||
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 (0x20 <= r && r <= 0x7e) {
|
||||
return true;
|
||||
@@ -473,7 +459,7 @@ bool is_printable(Rune r) {
|
||||
|
||||
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;
|
||||
isize n = str.len;
|
||||
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;
|
||||
|
||||
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;
|
||||
u8 *buf = gb_alloc_array(a, u8, buf_len);
|
||||
isize i = 0;
|
||||
@@ -675,7 +661,7 @@ String strip_carriage_return(gbAllocator a, String s) {
|
||||
// 0 == failure
|
||||
// 1 == original memory
|
||||
// 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_;
|
||||
isize n = s.len;
|
||||
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;
|
||||
|
||||
isize rune_count = 0;
|
||||
|
||||
@@ -3,7 +3,7 @@ struct StringHashKey {
|
||||
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 = {};
|
||||
hash_key.hash = fnv32a(s.text, s.len);
|
||||
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) {
|
||||
// NOTE(bill): If two string's hashes collide, compare the strings themselves
|
||||
return a.string == b.string;
|
||||
}
|
||||
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>
|
||||
struct StringMapEntry {
|
||||
@@ -30,34 +28,36 @@ struct StringMapEntry {
|
||||
|
||||
template <typename T>
|
||||
struct StringMap {
|
||||
using K = String;
|
||||
using V = T;
|
||||
Slice<MapIndex> hashes;
|
||||
Array<StringMapEntry<T> > entries;
|
||||
};
|
||||
|
||||
|
||||
template <typename T> void string_map_init (StringMap<T> *h, gbAllocator a, isize capacity = 16);
|
||||
template <typename T> void string_map_destroy (StringMap<T> *h);
|
||||
template <typename T> gb_internal void string_map_init (StringMap<T> *h, gbAllocator a, isize capacity = 16);
|
||||
template <typename T> gb_internal void string_map_destroy (StringMap<T> *h);
|
||||
|
||||
template <typename T> T * string_map_get (StringMap<T> *h, char const *key);
|
||||
template <typename T> T * string_map_get (StringMap<T> *h, String const &key);
|
||||
template <typename T> T * string_map_get (StringMap<T> *h, StringHashKey const &key);
|
||||
template <typename T> gb_internal T * string_map_get (StringMap<T> *h, char const *key);
|
||||
template <typename T> gb_internal T * string_map_get (StringMap<T> *h, String const &key);
|
||||
template <typename T> gb_internal T * string_map_get (StringMap<T> *h, StringHashKey const &key);
|
||||
|
||||
template <typename T> T & string_map_must_get (StringMap<T> *h, char const *key);
|
||||
template <typename T> T & string_map_must_get (StringMap<T> *h, String const &key);
|
||||
template <typename T> T & string_map_must_get (StringMap<T> *h, StringHashKey const &key);
|
||||
template <typename T> gb_internal T & string_map_must_get (StringMap<T> *h, char const *key);
|
||||
template <typename T> gb_internal T & string_map_must_get (StringMap<T> *h, String const &key);
|
||||
template <typename T> gb_internal T & string_map_must_get (StringMap<T> *h, StringHashKey const &key);
|
||||
|
||||
template <typename T> void string_map_set (StringMap<T> *h, StringHashKey const &key, T const &value);
|
||||
template <typename T> void string_map_set (StringMap<T> *h, String const &key, T const &value);
|
||||
template <typename T> void string_map_set (StringMap<T> *h, char const *key, T const &value);
|
||||
template <typename T> gb_internal void string_map_set (StringMap<T> *h, StringHashKey const &key, T const &value);
|
||||
template <typename T> gb_internal void string_map_set (StringMap<T> *h, String const &key, T const &value);
|
||||
template <typename T> gb_internal void string_map_set (StringMap<T> *h, char const *key, T const &value);
|
||||
|
||||
template <typename T> void string_map_remove (StringMap<T> *h, StringHashKey const &key);
|
||||
template <typename T> void string_map_clear (StringMap<T> *h);
|
||||
template <typename T> void string_map_grow (StringMap<T> *h);
|
||||
template <typename T> void string_map_rehash (StringMap<T> *h, isize new_count);
|
||||
template <typename T> void string_map_reserve (StringMap<T> *h, isize cap);
|
||||
template <typename T> gb_internal void string_map_remove (StringMap<T> *h, StringHashKey const &key);
|
||||
template <typename T> gb_internal void string_map_clear (StringMap<T> *h);
|
||||
template <typename T> gb_internal void string_map_grow (StringMap<T> *h);
|
||||
template <typename T> gb_internal void string_map_rehash (StringMap<T> *h, isize new_count);
|
||||
template <typename T> gb_internal void string_map_reserve (StringMap<T> *h, isize cap);
|
||||
|
||||
template <typename T>
|
||||
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);
|
||||
slice_init(&h->hashes, a, 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>
|
||||
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);
|
||||
array_free(&h->entries);
|
||||
}
|
||||
@@ -128,7 +128,7 @@ gb_inline void string_map_grow(StringMap<T> *h) {
|
||||
|
||||
|
||||
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++) {
|
||||
h->hashes.data[i] = MAP_SENTINEL;
|
||||
}
|
||||
@@ -146,7 +146,7 @@ void string_map_reset_entries(StringMap<T> *h) {
|
||||
}
|
||||
|
||||
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);
|
||||
if (h->entries.count*2 < h->hashes.count) {
|
||||
return;
|
||||
@@ -157,12 +157,12 @@ void string_map_reserve(StringMap<T> *h, isize cap) {
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
if (index != MAP_SENTINEL) {
|
||||
return &h->entries.data[index].value;
|
||||
@@ -171,34 +171,34 @@ T *string_map_get(StringMap<T> *h, StringHashKey const &key) {
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
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)));
|
||||
}
|
||||
|
||||
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;
|
||||
GB_ASSERT(index != MAP_SENTINEL);
|
||||
return h->entries.data[index].value;
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
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)));
|
||||
}
|
||||
|
||||
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;
|
||||
MapFindResult fr;
|
||||
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>
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
if (fr.entry_prev == MAP_SENTINEL) {
|
||||
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>
|
||||
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);
|
||||
if (fr.entry_index != MAP_SENTINEL) {
|
||||
string_map__erase(h, fr);
|
||||
@@ -263,10 +263,31 @@ void string_map_remove(StringMap<T> *h, StringHashKey const &key) {
|
||||
}
|
||||
|
||||
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);
|
||||
for (isize i = 0; i < h->hashes.count; i++) {
|
||||
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;
|
||||
}
|
||||
@@ -10,18 +10,18 @@ struct StringSet {
|
||||
};
|
||||
|
||||
|
||||
void string_set_init (StringSet *s, gbAllocator a, isize capacity = 16);
|
||||
void string_set_destroy(StringSet *s);
|
||||
void string_set_add (StringSet *s, String const &str);
|
||||
bool string_set_update (StringSet *s, String const &str); // returns true if it previously existed
|
||||
bool string_set_exists (StringSet *s, String const &str);
|
||||
void string_set_remove (StringSet *s, String const &str);
|
||||
void string_set_clear (StringSet *s);
|
||||
void string_set_grow (StringSet *s);
|
||||
void string_set_rehash (StringSet *s, isize new_count);
|
||||
gb_internal void string_set_init (StringSet *s, gbAllocator a, isize capacity = 16);
|
||||
gb_internal void string_set_destroy(StringSet *s);
|
||||
gb_internal void string_set_add (StringSet *s, String const &str);
|
||||
gb_internal bool string_set_update (StringSet *s, String const &str); // returns true if it previously existed
|
||||
gb_internal bool string_set_exists (StringSet *s, String const &str);
|
||||
gb_internal void string_set_remove (StringSet *s, String const &str);
|
||||
gb_internal void string_set_clear (StringSet *s);
|
||||
gb_internal void string_set_grow (StringSet *s);
|
||||
gb_internal void string_set_rehash (StringSet *s, isize new_count);
|
||||
|
||||
|
||||
gb_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));
|
||||
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
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++) {
|
||||
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);
|
||||
if (s->entries.count*2 < s->hashes.count) {
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -125,7 +125,7 @@ gb_inline bool string_set_exists(StringSet *s, String const &str) {
|
||||
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;
|
||||
MapFindResult fr;
|
||||
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;
|
||||
MapIndex index;
|
||||
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;
|
||||
if (fr.entry_prev == MAP_SENTINEL) {
|
||||
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);
|
||||
MapFindResult fr = string_set__find(s, key);
|
||||
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);
|
||||
for_array(i, s->hashes) {
|
||||
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;
|
||||
}
|
||||
@@ -1,14 +1,25 @@
|
||||
// thread_pool.cpp
|
||||
|
||||
struct WorkerTask;
|
||||
struct ThreadPool;
|
||||
|
||||
#define WORKER_TASK_PROC(name) isize name(void *data)
|
||||
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 {
|
||||
WorkerTask * next;
|
||||
WorkerTaskProc *do_work;
|
||||
void * data;
|
||||
ThreadPool * pool;
|
||||
};
|
||||
|
||||
|
||||
struct ThreadPool {
|
||||
gbAllocator allocator;
|
||||
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->stop = false;
|
||||
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);
|
||||
for_array(i, pool->threads) {
|
||||
Thread *t = &pool->threads[i];
|
||||
thread_init(t);
|
||||
}
|
||||
|
||||
for_array(i, pool->threads) {
|
||||
Thread *t = &pool->threads[i];
|
||||
thread_start(t, thread_pool_thread_proc, pool);
|
||||
thread_init_and_start(t, thread_pool_thread_proc, pool);
|
||||
}
|
||||
}
|
||||
|
||||
void thread_pool_destroy(ThreadPool *pool) {
|
||||
gb_internal void thread_pool_destroy(ThreadPool *pool) {
|
||||
mutex_lock(&pool->mutex);
|
||||
pool->stop = true;
|
||||
condition_broadcast(&pool->task_cond);
|
||||
@@ -51,65 +57,60 @@ void thread_pool_destroy(ThreadPool *pool) {
|
||||
|
||||
for_array(i, pool->threads) {
|
||||
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);
|
||||
mutex_destroy(&pool->mutex);
|
||||
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;
|
||||
}
|
||||
|
||||
WorkerTask *thread_pool_queue_pop(ThreadPool *pool) {
|
||||
gb_internal WorkerTask *thread_pool_queue_pop(ThreadPool *pool) {
|
||||
GB_ASSERT(pool->task_queue != nullptr);
|
||||
WorkerTask *task = pool->task_queue;
|
||||
pool->task_queue = task->next;
|
||||
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);
|
||||
task->next = pool->task_queue;
|
||||
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);
|
||||
mutex_lock(&pool->mutex);
|
||||
WorkerTask *task = gb_alloc_item(permanent_allocator(), WorkerTask);
|
||||
if (task == nullptr) {
|
||||
mutex_unlock(&pool->mutex);
|
||||
GB_PANIC("Out of memory");
|
||||
return false;
|
||||
}
|
||||
task->pool = pool;
|
||||
task->do_work = proc;
|
||||
task->data = data;
|
||||
|
||||
mutex_lock(&pool->mutex);
|
||||
thread_pool_queue_push(pool, task);
|
||||
GB_ASSERT(pool->ready >= 0);
|
||||
pool->ready++;
|
||||
pool->ready.fetch_add(1);
|
||||
condition_broadcast(&pool->task_cond);
|
||||
mutex_unlock(&pool->mutex);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void thread_pool_do_task(WorkerTask *task) {
|
||||
gb_internal void thread_pool_do_task(WorkerTask *task) {
|
||||
task->do_work(task->data);
|
||||
}
|
||||
|
||||
void thread_pool_wait(ThreadPool *pool) {
|
||||
gb_internal void thread_pool_wait(ThreadPool *pool) {
|
||||
if (pool->threads.count == 0) {
|
||||
while (!thread_pool_queue_empty(pool)) {
|
||||
thread_pool_do_task(thread_pool_queue_pop(pool));
|
||||
--pool->ready;
|
||||
pool->ready.fetch_sub(1);
|
||||
}
|
||||
GB_ASSERT(pool->ready == 0);
|
||||
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;
|
||||
|
||||
for (;;) {
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
#if defined(GB_SYSTEM_LINUX)
|
||||
#include <signal.h>
|
||||
#endif
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4505)
|
||||
#endif
|
||||
|
||||
struct BlockingMutex;
|
||||
struct RecursiveMutex;
|
||||
@@ -23,49 +27,46 @@ struct Thread {
|
||||
isize user_index;
|
||||
isize volatile return_value;
|
||||
|
||||
Semaphore * semaphore;
|
||||
isize stack_size;
|
||||
std::atomic<bool> is_running;
|
||||
};
|
||||
|
||||
|
||||
void mutex_init (BlockingMutex *m);
|
||||
void mutex_destroy (BlockingMutex *m);
|
||||
void mutex_lock (BlockingMutex *m);
|
||||
bool mutex_try_lock(BlockingMutex *m);
|
||||
void mutex_unlock (BlockingMutex *m);
|
||||
void mutex_init (RecursiveMutex *m);
|
||||
void mutex_destroy (RecursiveMutex *m);
|
||||
void mutex_lock (RecursiveMutex *m);
|
||||
bool mutex_try_lock(RecursiveMutex *m);
|
||||
void mutex_unlock (RecursiveMutex *m);
|
||||
gb_internal void mutex_init (BlockingMutex *m);
|
||||
gb_internal void mutex_destroy (BlockingMutex *m);
|
||||
gb_internal void mutex_lock (BlockingMutex *m);
|
||||
gb_internal bool mutex_try_lock(BlockingMutex *m);
|
||||
gb_internal void mutex_unlock (BlockingMutex *m);
|
||||
gb_internal void mutex_init (RecursiveMutex *m);
|
||||
gb_internal void mutex_destroy (RecursiveMutex *m);
|
||||
gb_internal void mutex_lock (RecursiveMutex *m);
|
||||
gb_internal bool mutex_try_lock(RecursiveMutex *m);
|
||||
gb_internal void mutex_unlock (RecursiveMutex *m);
|
||||
|
||||
void semaphore_init (Semaphore *s);
|
||||
void semaphore_destroy(Semaphore *s);
|
||||
void semaphore_post (Semaphore *s, i32 count);
|
||||
void semaphore_wait (Semaphore *s);
|
||||
void semaphore_release(Semaphore *s) { semaphore_post(s, 1); }
|
||||
gb_internal void semaphore_init (Semaphore *s);
|
||||
gb_internal void semaphore_destroy(Semaphore *s);
|
||||
gb_internal void semaphore_post (Semaphore *s, i32 count);
|
||||
gb_internal void semaphore_wait (Semaphore *s);
|
||||
gb_internal void semaphore_release(Semaphore *s) { semaphore_post(s, 1); }
|
||||
|
||||
|
||||
void condition_init(Condition *c);
|
||||
void condition_destroy(Condition *c);
|
||||
void condition_broadcast(Condition *c);
|
||||
void condition_signal(Condition *c);
|
||||
void condition_wait(Condition *c, BlockingMutex *m);
|
||||
void condition_wait_with_timeout(Condition *c, BlockingMutex *m, u32 timeout_in_ms);
|
||||
gb_internal void condition_init(Condition *c);
|
||||
gb_internal void condition_destroy(Condition *c);
|
||||
gb_internal void condition_broadcast(Condition *c);
|
||||
gb_internal void condition_signal(Condition *c);
|
||||
gb_internal void condition_wait(Condition *c, BlockingMutex *m);
|
||||
gb_internal void condition_wait_with_timeout(Condition *c, BlockingMutex *m, u32 timeout_in_ms);
|
||||
|
||||
u32 thread_current_id(void);
|
||||
gb_internal u32 thread_current_id(void);
|
||||
|
||||
void thread_init (Thread *t);
|
||||
void thread_destroy (Thread *t);
|
||||
void thread_start (Thread *t, ThreadProc *proc, void *data);
|
||||
void thread_start_with_stack(Thread *t, ThreadProc *proc, void *data, isize stack_size);
|
||||
void thread_join (Thread *t);
|
||||
bool thread_is_running (Thread const *t);
|
||||
void thread_set_name (Thread *t, char const *name);
|
||||
gb_internal void thread_init_and_start (Thread *t, ThreadProc *proc, void *data);
|
||||
gb_internal void thread_init_and_start_with_stack(Thread *t, ThreadProc *proc, void *data, isize stack_size);
|
||||
gb_internal void thread_join_and_destroy(Thread *t);
|
||||
gb_internal bool thread_is_running (Thread const *t);
|
||||
gb_internal void thread_set_name (Thread *t, char const *name);
|
||||
|
||||
void yield_thread(void);
|
||||
void yield_process(void);
|
||||
gb_internal void yield_thread(void);
|
||||
gb_internal void yield_process(void);
|
||||
|
||||
|
||||
struct MutexGuard {
|
||||
@@ -106,36 +107,36 @@ struct MutexGuard {
|
||||
struct BlockingMutex {
|
||||
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);
|
||||
}
|
||||
bool mutex_try_lock(BlockingMutex *m) {
|
||||
gb_internal bool mutex_try_lock(BlockingMutex *m) {
|
||||
return !!TryAcquireSRWLockExclusive(&m->srwlock);
|
||||
}
|
||||
void mutex_unlock(BlockingMutex *m) {
|
||||
gb_internal void mutex_unlock(BlockingMutex *m) {
|
||||
ReleaseSRWLockExclusive(&m->srwlock);
|
||||
}
|
||||
|
||||
struct RecursiveMutex {
|
||||
CRITICAL_SECTION win32_critical_section;
|
||||
};
|
||||
void mutex_init(RecursiveMutex *m) {
|
||||
gb_internal void mutex_init(RecursiveMutex *m) {
|
||||
InitializeCriticalSection(&m->win32_critical_section);
|
||||
}
|
||||
void mutex_destroy(RecursiveMutex *m) {
|
||||
gb_internal void mutex_destroy(RecursiveMutex *m) {
|
||||
DeleteCriticalSection(&m->win32_critical_section);
|
||||
}
|
||||
void mutex_lock(RecursiveMutex *m) {
|
||||
gb_internal void mutex_lock(RecursiveMutex *m) {
|
||||
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;
|
||||
}
|
||||
void mutex_unlock(RecursiveMutex *m) {
|
||||
gb_internal void mutex_unlock(RecursiveMutex *m) {
|
||||
LeaveCriticalSection(&m->win32_critical_section);
|
||||
}
|
||||
|
||||
@@ -143,16 +144,16 @@ struct MutexGuard {
|
||||
void *win32_handle;
|
||||
};
|
||||
|
||||
void semaphore_init(Semaphore *s) {
|
||||
gb_internal void semaphore_init(Semaphore *s) {
|
||||
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);
|
||||
}
|
||||
void semaphore_post(Semaphore *s, i32 count) {
|
||||
gb_internal void semaphore_post(Semaphore *s, i32 count) {
|
||||
ReleaseSemaphore(s->win32_handle, count, NULL);
|
||||
}
|
||||
void semaphore_wait(Semaphore *s) {
|
||||
gb_internal void semaphore_wait(Semaphore *s) {
|
||||
WaitForSingleObjectEx(s->win32_handle, INFINITE, FALSE);
|
||||
}
|
||||
|
||||
@@ -160,20 +161,20 @@ struct MutexGuard {
|
||||
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);
|
||||
}
|
||||
void condition_signal(Condition *c) {
|
||||
gb_internal void condition_signal(Condition *c) {
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -181,19 +182,19 @@ struct MutexGuard {
|
||||
struct BlockingMutex {
|
||||
pthread_mutex_t pthread_mutex;
|
||||
};
|
||||
void mutex_init(BlockingMutex *m) {
|
||||
gb_internal void mutex_init(BlockingMutex *m) {
|
||||
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);
|
||||
}
|
||||
void mutex_lock(BlockingMutex *m) {
|
||||
gb_internal void mutex_lock(BlockingMutex *m) {
|
||||
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;
|
||||
}
|
||||
void mutex_unlock(BlockingMutex *m) {
|
||||
gb_internal void mutex_unlock(BlockingMutex *m) {
|
||||
pthread_mutex_unlock(&m->pthread_mutex);
|
||||
}
|
||||
|
||||
@@ -201,21 +202,21 @@ struct MutexGuard {
|
||||
pthread_mutex_t pthread_mutex;
|
||||
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_settype(&m->pthread_mutexattr, PTHREAD_MUTEX_RECURSIVE);
|
||||
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);
|
||||
}
|
||||
void mutex_lock(RecursiveMutex *m) {
|
||||
gb_internal void mutex_lock(RecursiveMutex *m) {
|
||||
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;
|
||||
}
|
||||
void mutex_unlock(RecursiveMutex *m) {
|
||||
gb_internal void mutex_unlock(RecursiveMutex *m) {
|
||||
pthread_mutex_unlock(&m->pthread_mutex);
|
||||
}
|
||||
|
||||
@@ -224,18 +225,18 @@ struct MutexGuard {
|
||||
semaphore_t osx_handle;
|
||||
};
|
||||
|
||||
void semaphore_init (Semaphore *s) { semaphore_create(mach_task_self(), &s->osx_handle, SYNC_POLICY_FIFO, 0); }
|
||||
void semaphore_destroy(Semaphore *s) { semaphore_destroy(mach_task_self(), s->osx_handle); }
|
||||
void semaphore_post (Semaphore *s, i32 count) { while (count --> 0) semaphore_signal(s->osx_handle); }
|
||||
void semaphore_wait (Semaphore *s) { semaphore_wait(s->osx_handle); }
|
||||
gb_internal void semaphore_init (Semaphore *s) { semaphore_create(mach_task_self(), &s->osx_handle, SYNC_POLICY_FIFO, 0); }
|
||||
gb_internal void semaphore_destroy(Semaphore *s) { semaphore_destroy(mach_task_self(), s->osx_handle); }
|
||||
gb_internal void semaphore_post (Semaphore *s, i32 count) { while (count --> 0) semaphore_signal(s->osx_handle); }
|
||||
gb_internal void semaphore_wait (Semaphore *s) { semaphore_wait(s->osx_handle); }
|
||||
#elif defined(GB_SYSTEM_UNIX)
|
||||
struct Semaphore {
|
||||
sem_t unix_handle;
|
||||
};
|
||||
|
||||
void semaphore_init (Semaphore *s) { sem_init(&s->unix_handle, 0, 0); }
|
||||
void semaphore_destroy(Semaphore *s) { sem_destroy(&s->unix_handle); }
|
||||
void semaphore_post (Semaphore *s, i32 count) { while (count --> 0) sem_post(&s->unix_handle); }
|
||||
gb_internal void semaphore_init (Semaphore *s) { sem_init(&s->unix_handle, 0, 0); }
|
||||
gb_internal void semaphore_destroy(Semaphore *s) { sem_destroy(&s->unix_handle); }
|
||||
gb_internal void semaphore_post (Semaphore *s, i32 count) { while (count --> 0) sem_post(&s->unix_handle); }
|
||||
void semaphore_wait (Semaphore *s) { int i; do { i = sem_wait(&s->unix_handle); } while (i == -1 && errno == EINTR); }
|
||||
#else
|
||||
#error Implement Semaphore for this platform
|
||||
@@ -246,22 +247,22 @@ struct MutexGuard {
|
||||
pthread_cond_t pthread_cond;
|
||||
};
|
||||
|
||||
void condition_init(Condition *c) {
|
||||
gb_internal void condition_init(Condition *c) {
|
||||
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);
|
||||
}
|
||||
void condition_broadcast(Condition *c) {
|
||||
gb_internal void condition_broadcast(Condition *c) {
|
||||
pthread_cond_broadcast(&c->pthread_cond);
|
||||
}
|
||||
void condition_signal(Condition *c) {
|
||||
gb_internal void condition_signal(Condition *c) {
|
||||
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);
|
||||
}
|
||||
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 = {};
|
||||
abstime.tv_sec = timeout_in_ms/1000;
|
||||
abstime.tv_nsec = cast(long)(timeout_in_ms%1000)*1e6;
|
||||
@@ -269,51 +270,9 @@ struct MutexGuard {
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
struct Barrier {
|
||||
BlockingMutex mutex;
|
||||
Condition cond;
|
||||
isize index;
|
||||
isize generation_id;
|
||||
isize thread_count;
|
||||
};
|
||||
|
||||
void barrier_init(Barrier *b, isize thread_count) {
|
||||
mutex_init(&b->mutex);
|
||||
condition_init(&b->cond);
|
||||
b->index = 0;
|
||||
b->generation_id = 0;
|
||||
b->thread_count = 0;
|
||||
}
|
||||
|
||||
void barrier_destroy(Barrier *b) {
|
||||
condition_destroy(&b->cond);
|
||||
mutex_destroy(&b->mutex);
|
||||
}
|
||||
|
||||
// Returns true if it is the leader
|
||||
bool barrier_wait(Barrier *b) {
|
||||
mutex_lock(&b->mutex);
|
||||
defer (mutex_unlock(&b->mutex));
|
||||
isize local_gen = b->generation_id;
|
||||
b->index += 1;
|
||||
if (b->index < b->thread_count) {
|
||||
while (local_gen == b->generation_id && b->index < b->thread_count) {
|
||||
condition_wait(&b->cond, &b->mutex);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
b->index = 0;
|
||||
b->generation_id += 1;
|
||||
condition_broadcast(&b->cond);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
u32 thread_current_id(void) {
|
||||
gb_internal u32 thread_current_id(void) {
|
||||
u32 thread_id;
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
#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)
|
||||
_mm_pause();
|
||||
#elif defined(GB_SYSTEM_OSX)
|
||||
@@ -358,7 +317,7 @@ gb_inline void yield_thread(void) {
|
||||
#endif
|
||||
}
|
||||
|
||||
gb_inline void yield(void) {
|
||||
gb_internal gb_inline void yield(void) {
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
YieldProcessor();
|
||||
#else
|
||||
@@ -366,39 +325,19 @@ gb_inline void yield(void) {
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void thread_init(Thread *t) {
|
||||
gb_zero_item(t);
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
t->win32_handle = INVALID_HANDLE_VALUE;
|
||||
#else
|
||||
t->posix_handle = 0;
|
||||
#endif
|
||||
t->semaphore = gb_alloc_item(heap_allocator(), Semaphore);
|
||||
semaphore_init(t->semaphore);
|
||||
}
|
||||
|
||||
void thread_destroy(Thread *t) {
|
||||
thread_join(t);
|
||||
semaphore_destroy(t->semaphore);
|
||||
gb_free(heap_allocator(), t->semaphore);
|
||||
}
|
||||
|
||||
|
||||
void gb__thread_run(Thread *t) {
|
||||
semaphore_release(t->semaphore);
|
||||
gb_internal void private__thread_run(Thread *t) {
|
||||
t->return_value = t->proc(t);
|
||||
}
|
||||
|
||||
#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;
|
||||
t->is_running.store(true);
|
||||
gb__thread_run(t);
|
||||
private__thread_run(t);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
void *internal_thread_proc(void *arg) {
|
||||
gb_internal void *internal_thread_proc(void *arg) {
|
||||
#if (GB_SYSTEM_LINUX)
|
||||
// NOTE: Don't permit any signal delivery to threads on Linux.
|
||||
sigset_t mask = {};
|
||||
@@ -408,14 +347,20 @@ void gb__thread_run(Thread *t) {
|
||||
|
||||
Thread *t = cast(Thread *)arg;
|
||||
t->is_running.store(true);
|
||||
gb__thread_run(t);
|
||||
private__thread_run(t);
|
||||
return NULL;
|
||||
}
|
||||
#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(proc != NULL);
|
||||
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_init(&attr);
|
||||
defer (pthread_attr_destroy(&attr));
|
||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
|
||||
if (stack_size != 0) {
|
||||
pthread_attr_setstacksize(&attr, stack_size);
|
||||
}
|
||||
pthread_create(&t->posix_handle, &attr, internal_thread_proc, t);
|
||||
pthread_attr_destroy(&attr);
|
||||
}
|
||||
#endif
|
||||
|
||||
semaphore_wait(t->semaphore);
|
||||
}
|
||||
|
||||
void thread_join(Thread *t) {
|
||||
gb_internal void thread_join_and_destroy(Thread *t) {
|
||||
if (!t->is_running.load()) {
|
||||
return;
|
||||
}
|
||||
@@ -457,9 +400,9 @@ void thread_join(Thread *t) {
|
||||
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)
|
||||
#pragma pack(push, 8)
|
||||
typedef struct {
|
||||
@@ -494,3 +437,7 @@ void thread_set_name(Thread *t, char const *name) {
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
@@ -13,13 +13,13 @@ struct Timings {
|
||||
|
||||
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
u64 win32_time_stamp_time_now(void) {
|
||||
gb_internal u64 win32_time_stamp_time_now(void) {
|
||||
LARGE_INTEGER counter;
|
||||
QueryPerformanceCounter(&counter);
|
||||
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};
|
||||
if (!win32_perf_count_freq.QuadPart) {
|
||||
QueryPerformanceFrequency(&win32_perf_count_freq);
|
||||
@@ -33,11 +33,11 @@ u64 win32_time_stamp__freq(void) {
|
||||
|
||||
#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();
|
||||
}
|
||||
|
||||
u64 osx_time_stamp__freq(void) {
|
||||
gb_internal u64 osx_time_stamp__freq(void) {
|
||||
mach_timebase_info_data_t data;
|
||||
data.numer = 0;
|
||||
data.denom = 0;
|
||||
@@ -55,14 +55,14 @@ u64 osx_time_stamp__freq(void) {
|
||||
|
||||
#include <time.h>
|
||||
|
||||
u64 unix_time_stamp_time_now(void) {
|
||||
gb_internal u64 unix_time_stamp_time_now(void) {
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
|
||||
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;
|
||||
|
||||
if (freq == 0) {
|
||||
@@ -80,7 +80,7 @@ u64 unix_time_stamp__freq(void) {
|
||||
#error Implement system
|
||||
#endif
|
||||
|
||||
u64 time_stamp_time_now(void) {
|
||||
gb_internal u64 time_stamp_time_now(void) {
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
return win32_time_stamp_time_now();
|
||||
#elif defined(GB_SYSTEM_OSX)
|
||||
@@ -92,7 +92,7 @@ u64 time_stamp_time_now(void) {
|
||||
#endif
|
||||
}
|
||||
|
||||
u64 time_stamp__freq(void) {
|
||||
gb_internal u64 time_stamp__freq(void) {
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
return win32_time_stamp__freq();
|
||||
#elif defined(GB_SYSTEM_OSX)
|
||||
@@ -104,44 +104,44 @@ u64 time_stamp__freq(void) {
|
||||
#endif
|
||||
}
|
||||
|
||||
TimeStamp make_time_stamp(String const &label) {
|
||||
gb_internal TimeStamp make_time_stamp(String const &label) {
|
||||
TimeStamp ts = {0};
|
||||
ts.start = time_stamp_time_now();
|
||||
ts.label = label;
|
||||
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);
|
||||
t->total = make_time_stamp(label);
|
||||
t->freq = time_stamp__freq();
|
||||
}
|
||||
|
||||
void timings_destroy(Timings *t) {
|
||||
gb_internal void timings_destroy(Timings *t) {
|
||||
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) {
|
||||
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);
|
||||
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));
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -160,7 +160,7 @@ enum TimingUnit {
|
||||
|
||||
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) {
|
||||
case TimingUnit_Millisecond: return time_stamp_as_ms(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;
|
||||
char SPACES[SPACES_LEN+1] = {0};
|
||||
gb_memset(SPACES, ' ', SPACES_LEN);
|
||||
|
||||
@@ -151,10 +151,10 @@ gb_global isize max_keyword_size = 11;
|
||||
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);
|
||||
}
|
||||
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);
|
||||
|
||||
keyword_indices[s.len] = true;
|
||||
@@ -169,7 +169,7 @@ void add_keyword_hash_entry(String const &s, TokenKind kind) {
|
||||
entry->kind = kind;
|
||||
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++) {
|
||||
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<struct AstFile *> global_files; // index is file id
|
||||
|
||||
String get_file_path_string(i32 index);
|
||||
struct AstFile *thread_safe_get_ast_file_from_id(i32 index);
|
||||
gb_internal String get_file_path_string(i32 index);
|
||||
gb_internal struct AstFile *thread_safe_get_ast_file_from_id(i32 index);
|
||||
|
||||
struct TokenPos {
|
||||
i32 file_id;
|
||||
@@ -201,7 +201,7 @@ struct TokenPos {
|
||||
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) {
|
||||
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));
|
||||
}
|
||||
|
||||
bool operator==(TokenPos const &a, TokenPos const &b) { return token_pos_cmp(a, b) == 0; }
|
||||
bool operator!=(TokenPos const &a, TokenPos const &b) { return token_pos_cmp(a, b) != 0; }
|
||||
bool operator< (TokenPos const &a, TokenPos const &b) { return token_pos_cmp(a, b) < 0; }
|
||||
bool operator<=(TokenPos const &a, TokenPos const &b) { return token_pos_cmp(a, b) <= 0; }
|
||||
bool operator> (TokenPos const &a, TokenPos const &b) { return token_pos_cmp(a, b) > 0; }
|
||||
bool operator>=(TokenPos const &a, TokenPos const &b) { return token_pos_cmp(a, b) >= 0; }
|
||||
gb_internal gb_inline bool operator==(TokenPos const &a, TokenPos const &b) { return token_pos_cmp(a, b) == 0; }
|
||||
gb_internal gb_inline bool operator!=(TokenPos const &a, TokenPos const &b) { return token_pos_cmp(a, b) != 0; }
|
||||
gb_internal gb_inline bool operator< (TokenPos const &a, TokenPos const &b) { return token_pos_cmp(a, b) < 0; }
|
||||
gb_internal gb_inline bool operator<=(TokenPos const &a, TokenPos const &b) { return token_pos_cmp(a, b) <= 0; }
|
||||
gb_internal gb_inline bool operator> (TokenPos const &a, TokenPos const &b) { return token_pos_cmp(a, b) > 0; }
|
||||
gb_internal gb_inline bool operator>=(TokenPos const &a, TokenPos const &b) { return token_pos_cmp(a, b) >= 0; }
|
||||
|
||||
|
||||
TokenPos token_pos_add_column(TokenPos pos) {
|
||||
@@ -243,36 +243,36 @@ struct Token {
|
||||
Token empty_token = {Token_Invalid};
|
||||
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};
|
||||
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)};
|
||||
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";
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
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"
|
||||
|
||||
@@ -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;
|
||||
i32 column = t->column_minus_one+1;
|
||||
if (column < 1) {
|
||||
@@ -328,7 +328,7 @@ void tokenizer_err(Tokenizer *t, char const *msg, ...) {
|
||||
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;
|
||||
i32 column = t->column_minus_one+1;
|
||||
if (column < 1) {
|
||||
@@ -342,7 +342,7 @@ void tokenizer_err(Tokenizer *t, TokenPos const &pos, char const *msg, ...) {
|
||||
t->error_count++;
|
||||
}
|
||||
|
||||
void advance_to_next_rune(Tokenizer *t) {
|
||||
gb_internal void advance_to_next_rune(Tokenizer *t) {
|
||||
if (t->curr_rune == '\n') {
|
||||
t->column_minus_one = -1;
|
||||
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->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_Empty, /*LoadedFile_Empty*/
|
||||
TokenizerInit_FileTooLarge, /*LoadedFile_FileTooLarge*/
|
||||
@@ -395,7 +395,7 @@ TokenizerInitError loaded_file_error_map_to_tokenizer[LoadedFile_COUNT] = {
|
||||
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(
|
||||
alloc_cstring(temporary_allocator(), fullpath),
|
||||
&t->loaded_file,
|
||||
@@ -416,7 +416,7 @@ TokenizerInitError init_tokenizer_from_fullpath(Tokenizer *t, String const &full
|
||||
return err;
|
||||
}
|
||||
|
||||
gb_inline i32 digit_value(Rune r) {
|
||||
gb_internal gb_inline i32 digit_value(Rune r) {
|
||||
switch (r) {
|
||||
case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
|
||||
return r - '0';
|
||||
@@ -428,20 +428,20 @@ gb_inline i32 digit_value(Rune r) {
|
||||
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 == '_') {
|
||||
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) {
|
||||
return t->read_curr[offset];
|
||||
}
|
||||
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->string = {t->curr, 1};
|
||||
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;
|
||||
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) {
|
||||
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) {
|
||||
for (;;) {
|
||||
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);
|
||||
|
||||
token->kind = Token_Invalid;
|
||||
|
||||
741
src/types.cpp
741
src/types.cpp
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ extern "C" {
|
||||
#pragma warning(pop)
|
||||
|
||||
|
||||
bool rune_is_letter(Rune r) {
|
||||
gb_internal bool rune_is_letter(Rune r) {
|
||||
if (r < 0x80) {
|
||||
if (r == '_') {
|
||||
return true;
|
||||
@@ -25,14 +25,14 @@ bool rune_is_letter(Rune r) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool rune_is_digit(Rune r) {
|
||||
gb_internal bool rune_is_digit(Rune r) {
|
||||
if (r < 0x80) {
|
||||
return (cast(u32)r - '0') < 10;
|
||||
}
|
||||
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 == '_') {
|
||||
return true;
|
||||
@@ -55,7 +55,7 @@ bool rune_is_letter_or_digit(Rune r) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool rune_is_whitespace(Rune r) {
|
||||
gb_internal bool rune_is_whitespace(Rune r) {
|
||||
switch (r) {
|
||||
case ' ':
|
||||
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;
|
||||
Rune codepoint = GB_RUNE_INVALID;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user