mirror of
https://github.com/Ed94/Odin.git
synced 2026-07-21 00:46:47 +00:00
Merge branch 'master' into separate-int-word-sizes
This commit is contained in:
@@ -264,6 +264,7 @@ struct BuildContext {
|
||||
String microarch;
|
||||
BuildModeKind build_mode;
|
||||
bool generate_docs;
|
||||
bool custom_optimization_level;
|
||||
i32 optimization_level;
|
||||
bool show_timings;
|
||||
TimingsExportFormat export_timings_format;
|
||||
@@ -1309,6 +1310,12 @@ gb_internal void init_build_context(TargetMetrics *cross_target) {
|
||||
gb_exit(1);
|
||||
}
|
||||
|
||||
if (bc->ODIN_DEBUG && !bc->custom_optimization_level) {
|
||||
// NOTE(bill): when building with `-debug` but not specifying an optimization level
|
||||
// default to `-o:none` to improve the debug symbol generation by default
|
||||
bc->optimization_level = -1; // -o:none
|
||||
}
|
||||
|
||||
bc->optimization_level = gb_clamp(bc->optimization_level, -1, 2);
|
||||
|
||||
// ENFORCE DYNAMIC MAP CALLS
|
||||
@@ -1322,9 +1329,6 @@ gb_internal void init_build_context(TargetMetrics *cross_target) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#undef LINK_FLAG_X64
|
||||
#undef LINK_FLAG_386
|
||||
}
|
||||
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
|
||||
@@ -1688,6 +1688,8 @@ gb_internal bool check_unary_op(CheckerContext *c, Operand *o, Token op) {
|
||||
if (is_type_integer(type)) {
|
||||
error_line("\tSuggestion: Did you mean to use the bitwise not operator '~'?\n");
|
||||
}
|
||||
} else {
|
||||
o->type = t_untyped_bool;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
+15
-8
@@ -378,6 +378,17 @@ gb_internal void add_polymorphic_record_entity(CheckerContext *ctx, Ast *node, T
|
||||
rw_mutex_unlock(&ctx->info->gen_types_mutex);
|
||||
}
|
||||
|
||||
|
||||
bool check_constant_parameter_value(Type *type, Ast *expr) {
|
||||
if (!is_type_constant_type(type)) {
|
||||
gbString str = type_to_string(type);
|
||||
defer (gb_string_free(str));
|
||||
error(expr, "A parameter must be a valid constant type, got %s", str);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
gb_internal Type *check_record_polymorphic_params(CheckerContext *ctx, Ast *polymorphic_params,
|
||||
bool *is_polymorphic_,
|
||||
Ast *node, Array<Operand> *poly_operands) {
|
||||
@@ -477,10 +488,8 @@ gb_internal Type *check_record_polymorphic_params(CheckerContext *ctx, Ast *poly
|
||||
type = t_invalid;
|
||||
}
|
||||
|
||||
if (!is_type_param && !is_type_constant_type(type)) {
|
||||
gbString str = type_to_string(type);
|
||||
error(params[i], "A parameter must be a valid constant type, got %s", str);
|
||||
gb_string_free(str);
|
||||
if (!is_type_param && check_constant_parameter_value(type, params[i])) {
|
||||
// failed
|
||||
}
|
||||
|
||||
Scope *scope = ctx->scope;
|
||||
@@ -1757,10 +1766,8 @@ gb_internal Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_para
|
||||
p->flags &= ~FieldFlag_by_ptr;
|
||||
}
|
||||
|
||||
if (!is_type_constant_type(type) && !is_type_polymorphic(type)) {
|
||||
gbString str = type_to_string(type);
|
||||
error(params[i], "A parameter must be a valid constant type, got %s", str);
|
||||
gb_string_free(str);
|
||||
if (!is_type_polymorphic(type) && check_constant_parameter_value(type, params[i])) {
|
||||
// failed
|
||||
}
|
||||
|
||||
param = alloc_entity_const_param(scope, name->Ident.token, type, poly_const, is_type_polymorphic(type));
|
||||
|
||||
+28
-11
@@ -1,3 +1,6 @@
|
||||
#if defined(GB_SYSTEM_LINUX)
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
gb_internal gb_inline void zero_size(void *ptr, isize len) {
|
||||
memset(ptr, 0, len);
|
||||
@@ -121,7 +124,6 @@ struct PlatformMemoryBlock {
|
||||
PlatformMemoryBlock *prev, *next;
|
||||
};
|
||||
|
||||
|
||||
gb_global std::atomic<isize> global_platform_memory_total_usage;
|
||||
gb_global PlatformMemoryBlock global_platform_memory_block_sentinel;
|
||||
|
||||
@@ -177,12 +179,12 @@ gb_internal 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;
|
||||
}
|
||||
gb_internal void platform_virtual_memory_free(PlatformMemoryBlock *block) {
|
||||
isize size = block->total_size;
|
||||
global_platform_memory_total_usage -= size;
|
||||
global_platform_memory_total_usage.fetch_sub(size);
|
||||
munmap(block, size);
|
||||
}
|
||||
gb_internal void platform_virtual_memory_protect(void *memory, isize size) {
|
||||
@@ -396,6 +398,8 @@ gb_internal gbAllocator heap_allocator(void) {
|
||||
return a;
|
||||
}
|
||||
|
||||
gb_internal std::atomic<isize> total_heap_memory_allocated;
|
||||
|
||||
|
||||
gb_internal GB_ALLOCATOR_PROC(heap_allocator_proc) {
|
||||
void *ptr = nullptr;
|
||||
@@ -403,7 +407,6 @@ gb_internal GB_ALLOCATOR_PROC(heap_allocator_proc) {
|
||||
gb_unused(old_size);
|
||||
|
||||
|
||||
|
||||
// TODO(bill): Throughly test!
|
||||
switch (type) {
|
||||
#if defined(GB_COMPILER_MSVC)
|
||||
@@ -436,28 +439,34 @@ gb_internal GB_ALLOCATOR_PROC(heap_allocator_proc) {
|
||||
#elif defined(GB_SYSTEM_LINUX)
|
||||
// TODO(bill): *nix version that's decent
|
||||
case gbAllocation_Alloc: {
|
||||
ptr = aligned_alloc(alignment, (size + alignment - 1) & ~(alignment - 1));
|
||||
isize total_size = (size + alignment - 1) & ~(alignment - 1);
|
||||
total_heap_memory_allocated.fetch_add(total_size);
|
||||
ptr = aligned_alloc(alignment, total_size);
|
||||
gb_zero_size(ptr, size);
|
||||
} break;
|
||||
|
||||
case gbAllocation_Free:
|
||||
if (old_memory != nullptr) {
|
||||
total_heap_memory_allocated.fetch_sub(malloc_usable_size(old_memory));
|
||||
free(old_memory);
|
||||
}
|
||||
break;
|
||||
|
||||
case gbAllocation_Resize:
|
||||
case gbAllocation_Resize: {
|
||||
if (size == 0) {
|
||||
if (old_memory != nullptr) {
|
||||
total_heap_memory_allocated.fetch_sub(malloc_usable_size(old_memory));
|
||||
free(old_memory);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
alignment = gb_max(alignment, gb_align_of(max_align_t));
|
||||
|
||||
|
||||
if (old_memory == nullptr) {
|
||||
ptr = aligned_alloc(alignment, (size + alignment - 1) & ~(alignment - 1));
|
||||
isize total_size = (size + alignment - 1) & ~(alignment - 1);
|
||||
total_heap_memory_allocated.fetch_add(total_size);
|
||||
ptr = aligned_alloc(alignment, total_size);
|
||||
gb_zero_size(ptr, size);
|
||||
break;
|
||||
}
|
||||
@@ -466,11 +475,19 @@ gb_internal GB_ALLOCATOR_PROC(heap_allocator_proc) {
|
||||
break;
|
||||
}
|
||||
|
||||
ptr = aligned_alloc(alignment, (size + alignment - 1) & ~(alignment - 1));
|
||||
size_t actual_old_size = malloc_usable_size(old_memory);
|
||||
if (size <= actual_old_size) {
|
||||
ptr = old_memory;
|
||||
break;
|
||||
}
|
||||
|
||||
isize total_size = (size + alignment - 1) & ~(alignment - 1);
|
||||
total_heap_memory_allocated.fetch_add(total_size);
|
||||
ptr = aligned_alloc(alignment, total_size);
|
||||
gb_memmove(ptr, old_memory, old_size);
|
||||
free(old_memory);
|
||||
gb_zero_size(cast(u8 *)ptr + old_size, gb_max(size-old_size, 0));
|
||||
break;
|
||||
} break;
|
||||
#else
|
||||
// TODO(bill): *nix version that's decent
|
||||
case gbAllocation_Alloc: {
|
||||
|
||||
@@ -436,6 +436,32 @@ gb_internal void syntax_error_va(TokenPos const &pos, TokenPos end, char const *
|
||||
}
|
||||
}
|
||||
|
||||
gb_internal void syntax_error_with_verbose_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);
|
||||
// NOTE(bill): Duplicate error, skip it
|
||||
if (pos.line == 0) {
|
||||
error_out_coloured("Syntax_Error: ", TerminalStyle_Normal, TerminalColour_Red);
|
||||
error_out_va(fmt, va);
|
||||
error_out("\n");
|
||||
} else if (global_error_collector.prev != pos) {
|
||||
global_error_collector.prev = pos;
|
||||
error_out_pos(pos);
|
||||
if (has_ansi_terminal_colours()) {
|
||||
error_out_coloured("Syntax_Error: ", TerminalStyle_Normal, TerminalColour_Red);
|
||||
}
|
||||
error_out_va(fmt, va);
|
||||
error_out("\n");
|
||||
show_error_on_line(pos, end);
|
||||
}
|
||||
mutex_unlock(&global_error_collector.mutex);
|
||||
if (global_error_collector.count > MAX_ERROR_COLLECTOR_COUNT()) {
|
||||
gb_exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
@@ -515,6 +541,14 @@ gb_internal void syntax_warning(Token const &token, char const *fmt, ...) {
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
gb_internal void syntax_error_with_verbose(TokenPos pos, TokenPos end, char const *fmt, ...) {
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
syntax_error_with_verbose_va(pos, end, fmt, va);
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
|
||||
|
||||
gb_internal void compiler_error(char const *fmt, ...) {
|
||||
va_list va;
|
||||
|
||||
@@ -514,6 +514,9 @@ gb_internal bool lb_is_matrix_simdable(Type *t) {
|
||||
// it's not aligned well enough to use the vector instructions
|
||||
return false;
|
||||
}
|
||||
if ((mt->Matrix.row_count & 1) ^ (mt->Matrix.column_count & 1)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (elem->kind == Type_Basic) {
|
||||
switch (elem->Basic.kind) {
|
||||
@@ -2833,7 +2836,7 @@ gb_internal lbValue lb_make_soa_pointer(lbProcedure *p, Type *type, lbValue cons
|
||||
lbValue ptr = lb_emit_struct_ep(p, v.addr, 0);
|
||||
lbValue idx = lb_emit_struct_ep(p, v.addr, 1);
|
||||
lb_emit_store(p, ptr, addr);
|
||||
lb_emit_store(p, idx, index);
|
||||
lb_emit_store(p, idx, lb_emit_conv(p, index, t_int));
|
||||
|
||||
return lb_addr_load(p, v);
|
||||
}
|
||||
|
||||
@@ -1035,12 +1035,16 @@ gb_internal bool parse_build_flags(Array<String> args) {
|
||||
case BuildFlag_OptimizationMode: {
|
||||
GB_ASSERT(value.kind == ExactValue_String);
|
||||
if (value.value_string == "none") {
|
||||
build_context.custom_optimization_level = true;
|
||||
build_context.optimization_level = -1;
|
||||
} else if (value.value_string == "minimal") {
|
||||
build_context.custom_optimization_level = true;
|
||||
build_context.optimization_level = 0;
|
||||
} else if (value.value_string == "size") {
|
||||
build_context.custom_optimization_level = true;
|
||||
build_context.optimization_level = 1;
|
||||
} else if (value.value_string == "speed") {
|
||||
build_context.custom_optimization_level = true;
|
||||
build_context.optimization_level = 2;
|
||||
} else {
|
||||
gb_printf_err("Invalid optimization mode for -o:<string>, got %.*s\n", LIT(value.value_string));
|
||||
|
||||
+47
-3
@@ -418,6 +418,25 @@ gb_internal void error(Ast *node, char const *fmt, ...) {
|
||||
}
|
||||
}
|
||||
|
||||
gb_internal void syntax_error_with_verbose(Ast *node, char const *fmt, ...) {
|
||||
Token token = {};
|
||||
TokenPos end_pos = {};
|
||||
if (node != nullptr) {
|
||||
token = ast_token(node);
|
||||
end_pos = ast_end_pos(node);
|
||||
}
|
||||
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
syntax_error_with_verbose_va(token.pos, end_pos, fmt, va);
|
||||
va_end(va);
|
||||
if (node != nullptr && node->file_id != 0) {
|
||||
AstFile *f = node->thread_safe_file();
|
||||
f->error_count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
gb_internal void error_no_newline(Ast *node, char const *fmt, ...) {
|
||||
Token token = {};
|
||||
if (node != nullptr) {
|
||||
@@ -496,11 +515,17 @@ gb_internal Ast *ast_tag_expr(AstFile *f, Token token, Token name, Ast *expr) {
|
||||
|
||||
gb_internal Ast *ast_unary_expr(AstFile *f, Token op, Ast *expr) {
|
||||
Ast *result = alloc_ast_node(f, Ast_UnaryExpr);
|
||||
|
||||
if (expr && expr->kind == Ast_OrReturnExpr) {
|
||||
syntax_error_with_verbose(expr, "'or_return' within an unary expression not wrapped in parentheses (...)");
|
||||
}
|
||||
|
||||
result->UnaryExpr.op = op;
|
||||
result->UnaryExpr.expr = expr;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
gb_internal Ast *ast_binary_expr(AstFile *f, Token op, Ast *left, Ast *right) {
|
||||
Ast *result = alloc_ast_node(f, Ast_BinaryExpr);
|
||||
|
||||
@@ -513,6 +538,13 @@ gb_internal Ast *ast_binary_expr(AstFile *f, Token op, Ast *left, Ast *right) {
|
||||
right = ast_bad_expr(f, op, op);
|
||||
}
|
||||
|
||||
if (left->kind == Ast_OrReturnExpr) {
|
||||
syntax_error_with_verbose(left, "'or_return' within a binary expression not wrapped in parentheses (...)");
|
||||
}
|
||||
if (right->kind == Ast_OrReturnExpr) {
|
||||
syntax_error_with_verbose(right, "'or_return' within a binary expression not wrapped in parentheses (...)");
|
||||
}
|
||||
|
||||
result->BinaryExpr.op = op;
|
||||
result->BinaryExpr.left = left;
|
||||
result->BinaryExpr.right = right;
|
||||
@@ -2765,6 +2797,12 @@ gb_internal Ast *parse_call_expr(AstFile *f, Ast *operand) {
|
||||
return call;
|
||||
}
|
||||
|
||||
gb_internal void parse_check_or_return(Ast *operand, char const *msg) {
|
||||
if (operand && operand->kind == Ast_OrReturnExpr) {
|
||||
syntax_error_with_verbose(operand, "'or_return' use within %s is not wrapped in parentheses (...)", msg);
|
||||
}
|
||||
}
|
||||
|
||||
gb_internal Ast *parse_atom_expr(AstFile *f, Ast *operand, bool lhs) {
|
||||
if (operand == nullptr) {
|
||||
if (f->allow_type) return nullptr;
|
||||
@@ -2778,6 +2816,7 @@ gb_internal Ast *parse_atom_expr(AstFile *f, Ast *operand, bool lhs) {
|
||||
while (loop) {
|
||||
switch (f->curr_token.kind) {
|
||||
case Token_OpenParen:
|
||||
parse_check_or_return(operand, "call expression");
|
||||
operand = parse_call_expr(f, operand);
|
||||
break;
|
||||
|
||||
@@ -2785,12 +2824,11 @@ gb_internal Ast *parse_atom_expr(AstFile *f, Ast *operand, bool lhs) {
|
||||
Token token = advance_token(f);
|
||||
switch (f->curr_token.kind) {
|
||||
case Token_Ident:
|
||||
parse_check_or_return(operand, "selector expression");
|
||||
operand = ast_selector_expr(f, token, operand, parse_ident(f));
|
||||
break;
|
||||
// case Token_Integer:
|
||||
// operand = ast_selector_expr(f, token, operand, parse_expr(f, lhs));
|
||||
// break;
|
||||
case Token_OpenParen: {
|
||||
parse_check_or_return(operand, "type assertion");
|
||||
Token open = expect_token(f, Token_OpenParen);
|
||||
Ast *type = parse_type(f);
|
||||
Token close = expect_token(f, Token_CloseParen);
|
||||
@@ -2798,6 +2836,7 @@ gb_internal Ast *parse_atom_expr(AstFile *f, Ast *operand, bool lhs) {
|
||||
} break;
|
||||
|
||||
case Token_Question: {
|
||||
parse_check_or_return(operand, ".? based type assertion");
|
||||
Token question = expect_token(f, Token_Question);
|
||||
Ast *type = ast_unary_expr(f, question, nullptr);
|
||||
operand = ast_type_assertion(f, operand, token, type);
|
||||
@@ -2813,6 +2852,7 @@ gb_internal Ast *parse_atom_expr(AstFile *f, Ast *operand, bool lhs) {
|
||||
} break;
|
||||
|
||||
case Token_ArrowRight: {
|
||||
parse_check_or_return(operand, "-> based call expression");
|
||||
Token token = advance_token(f);
|
||||
|
||||
operand = ast_selector_expr(f, token, operand, parse_ident(f));
|
||||
@@ -2870,11 +2910,14 @@ gb_internal Ast *parse_atom_expr(AstFile *f, Ast *operand, bool lhs) {
|
||||
if (indices[0] == nullptr || indices[1] == nullptr) {
|
||||
syntax_error(open, "Matrix index expressions require both row and column indices");
|
||||
}
|
||||
parse_check_or_return(operand, "matrix index expression");
|
||||
operand = ast_matrix_index_expr(f, operand, open, close, interval, indices[0], indices[1]);
|
||||
} else {
|
||||
parse_check_or_return(operand, "slice expression");
|
||||
operand = ast_slice_expr(f, operand, open, close, interval, indices[0], indices[1]);
|
||||
}
|
||||
} else {
|
||||
parse_check_or_return(operand, "index expression");
|
||||
operand = ast_index_expr(f, operand, indices[0], open, close);
|
||||
}
|
||||
|
||||
@@ -2882,6 +2925,7 @@ gb_internal Ast *parse_atom_expr(AstFile *f, Ast *operand, bool lhs) {
|
||||
} break;
|
||||
|
||||
case Token_Pointer: // Deference
|
||||
parse_check_or_return(operand, "dereference");
|
||||
operand = ast_deref_expr(f, operand, expect_token(f, Token_Pointer));
|
||||
break;
|
||||
|
||||
|
||||
+3
-1
@@ -114,7 +114,9 @@ gb_internal MapIndex map__add_entry(PtrMap<K, V> *h, K key) {
|
||||
PtrMapEntry<K, V> e = {};
|
||||
e.key = key;
|
||||
e.next = MAP_SENTINEL;
|
||||
map__reserve_entries(h, h->count+1);
|
||||
if (h->count+1 >= h->entries_capacity) {
|
||||
map__reserve_entries(h, gb_max(h->entries_capacity*2, 4));
|
||||
}
|
||||
h->entries[h->count++] = e;
|
||||
return cast(MapIndex)(h->count-1);
|
||||
}
|
||||
|
||||
+3
-1
@@ -96,7 +96,9 @@ gb_internal MapIndex string_map__add_entry(StringMap<T> *h, u32 hash, String con
|
||||
e.key = key;
|
||||
e.hash = hash;
|
||||
e.next = MAP_SENTINEL;
|
||||
string_map__reserve_entries(h, h->count+1);
|
||||
if (h->count+1 >= h->entries_capacity) {
|
||||
string_map__reserve_entries(h, gb_max(h->entries_capacity*2, 4));
|
||||
}
|
||||
h->entries[h->count++] = e;
|
||||
return cast(MapIndex)(h->count-1);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user