From cb1080d56c7a5d26f344a41ea6553bf154509072 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 10 Jan 2022 13:31:34 +0000 Subject: Fix `check_procedure_bodies` to allow multiple threads caused by a typo --- src/checker.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src/checker.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index 667146eda..c270e8210 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -4941,7 +4941,6 @@ void check_procedure_bodies(Checker *c) { if (!build_context.threaded_checker) { worker_count = 0; } - worker_count = 0; if (worker_count == 0) { auto *this_queue = &c->procs_to_check_queue; -- cgit v1.2.3 From 7cc265e14ce3ec08a5908d31441000bdcb4ac645 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 10 Jan 2022 14:50:28 +0000 Subject: Add mutex guards for signature scopes --- src/array.cpp | 4 ++++ src/check_decl.cpp | 2 +- src/check_expr.cpp | 2 ++ src/check_stmt.cpp | 2 +- src/checker.cpp | 2 +- src/common_memory.cpp | 34 ++++++++++++++++++++++++---------- src/threading.cpp | 34 ++++++++++++++++++++++++++++++++++ 7 files changed, 67 insertions(+), 13 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/array.cpp b/src/array.cpp index c41125c6d..ac3727978 100644 --- a/src/array.cpp +++ b/src/array.cpp @@ -77,15 +77,19 @@ template Slice slice_from_array(Array const &a); template Slice slice_make(gbAllocator const &allocator, isize count) { + GB_ASSERT(count >= 0); Slice s = {}; s.data = gb_alloc_array(allocator, T, count); + GB_ASSERT(s.data != nullptr); s.count = count; return s; } template void slice_init(Slice *s, gbAllocator const &allocator, isize count) { + GB_ASSERT(count >= 0); s->data = gb_alloc_array(allocator, T, count); + GB_ASSERT(s->data != nullptr); s->count = count; } diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 42f68203c..55ad67abf 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -1286,7 +1286,7 @@ void check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *decl, Type *ty using_entities.allocator = heap_allocator(); defer (array_free(&using_entities)); - { + MUTEX_GUARD_BLOCK(ctx->scope->mutex) { if (type->Proc.param_count > 0) { TypeTuple *params = &type->Proc.params->Tuple; for_array(i, params->variables) { diff --git a/src/check_expr.cpp b/src/check_expr.cpp index cfffffd9f..1162cefee 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -4021,10 +4021,12 @@ void check_did_you_mean_scope(String const &name, Scope *scope) { DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), scope->elements.entries.count, name); defer (did_you_mean_destroy(&d)); + mutex_lock(&scope->mutex); for_array(i, scope->elements.entries) { Entity *e = scope->elements.entries[i].value; did_you_mean_append(&d, e->token.string); } + mutex_unlock(&scope->mutex); check_did_you_mean_print(&d); } diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index 396388629..94b7561c7 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -607,7 +607,7 @@ bool check_using_stmt_entity(CheckerContext *ctx, AstUsingStmt *us, Ast *expr, b case Entity_ImportName: { Scope *scope = e->ImportName.scope; - for_array(i, scope->elements.entries) { + 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; if (!is_entity_exported(decl)) continue; diff --git a/src/checker.cpp b/src/checker.cpp index c270e8210..58c71a176 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -622,7 +622,7 @@ void check_scope_usage(Checker *c, Scope *scope) { Array vetted_entities = {}; array_init(&vetted_entities, heap_allocator()); - for_array(i, scope->elements.entries) { + MUTEX_GUARD_BLOCK(scope->mutex) for_array(i, scope->elements.entries) { Entity *e = scope->elements.entries[i].value; if (e == nullptr) continue; VettedEntity ve = {}; diff --git a/src/common_memory.cpp b/src/common_memory.cpp index 2d7a7a246..096c35b5c 100644 --- a/src/common_memory.cpp +++ b/src/common_memory.cpp @@ -325,18 +325,32 @@ GB_ALLOCATOR_PROC(heap_allocator_proc) { // TODO(bill): Throughly test! switch (type) { #if defined(GB_COMPILER_MSVC) - case gbAllocation_Alloc: { - isize aligned_size = align_formula_isize(size, alignment); - // TODO(bill): Make sure this is aligned correctly - ptr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, aligned_size); - } break; + case gbAllocation_Alloc: + if (size == 0) { + return NULL; + } else { + isize aligned_size = align_formula_isize(size, alignment); + // TODO(bill): Make sure this is aligned correctly + ptr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, aligned_size); + } + break; case gbAllocation_Free: - HeapFree(GetProcessHeap(), 0, old_memory); + if (old_memory != nullptr) { + HeapFree(GetProcessHeap(), 0, old_memory); + } + break; + case gbAllocation_Resize: + if (old_memory != nullptr && size > 0) { + isize aligned_size = align_formula_isize(size, alignment); + ptr = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, old_memory, aligned_size); + } else if (old_memory != nullptr) { + HeapFree(GetProcessHeap(), 0, old_memory); + } else if (size != 0) { + isize aligned_size = align_formula_isize(size, alignment); + // TODO(bill): Make sure this is aligned correctly + ptr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, aligned_size); + } break; - case gbAllocation_Resize: { - isize aligned_size = align_formula_isize(size, alignment); - ptr = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, old_memory, aligned_size); - } break; #elif defined(GB_SYSTEM_LINUX) // TODO(bill): *nix version that's decent case gbAllocation_Alloc: { diff --git a/src/threading.cpp b/src/threading.cpp index b318e4ff1..e848bba00 100644 --- a/src/threading.cpp +++ b/src/threading.cpp @@ -68,6 +68,40 @@ void yield_thread(void); void yield_process(void); +struct MutexGuard { + MutexGuard() = delete; + MutexGuard(MutexGuard const &) = delete; + + MutexGuard(BlockingMutex *bm) : bm{bm} { + mutex_lock(this->bm); + } + MutexGuard(RecursiveMutex *rm) : rm{rm} { + mutex_lock(this->rm); + } + MutexGuard(BlockingMutex &bm) : bm{&bm} { + mutex_lock(this->bm); + } + MutexGuard(RecursiveMutex &rm) : rm{&rm} { + mutex_lock(this->rm); + } + ~MutexGuard() { + if (this->bm) { + mutex_unlock(this->bm); + } else if (this->rm) { + mutex_unlock(this->rm); + } + } + + operator bool() const { return true; } + + BlockingMutex *bm; + RecursiveMutex *rm; +}; + +#define MUTEX_GUARD_BLOCK(m) if (MutexGuard GB_DEFER_3(_mutex_guard_) = m) +#define MUTEX_GUARD(m) MutexGuard GB_DEFER_3(_mutex_guard_) = m + + #if defined(GB_SYSTEM_WINDOWS) struct BlockingMutex { SRWLOCK srwlock; -- cgit v1.2.3 From 847b05013f71c69a4123fe5a4606c88039b716a3 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 11 Jan 2022 10:56:07 +0000 Subject: Disable `DEFAULT_TO_THREADED_CHECKER` until race condition is found --- src/bug_report.cpp | 26 +++++++++++++------------- src/build_settings.cpp | 2 +- src/check_decl.cpp | 9 ++++----- src/checker.cpp | 10 +++++----- src/checker.hpp | 2 +- 5 files changed, 24 insertions(+), 25 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/bug_report.cpp b/src/bug_report.cpp index 27e7fcf9a..9a1cb2254 100644 --- a/src/bug_report.cpp +++ b/src/bug_report.cpp @@ -140,7 +140,7 @@ void report_windows_product_type(DWORD ProductType) { break; default: - gb_printf("Unknown Edition (%08x)", ProductType); + gb_printf("Unknown Edition (%08x)", cast(unsigned)ProductType); } } #endif @@ -316,14 +316,14 @@ void print_bug_report_help() { } if (false) { - gb_printf("dwMajorVersion: %d\n", osvi.dwMajorVersion); - gb_printf("dwMinorVersion: %d\n", osvi.dwMinorVersion); - gb_printf("dwBuildNumber: %d\n", osvi.dwBuildNumber); - gb_printf("dwPlatformId: %d\n", osvi.dwPlatformId); - gb_printf("wServicePackMajor: %d\n", osvi.wServicePackMajor); - gb_printf("wServicePackMinor: %d\n", osvi.wServicePackMinor); - gb_printf("wSuiteMask: %d\n", osvi.wSuiteMask); - gb_printf("wProductType: %d\n", osvi.wProductType); + gb_printf("dwMajorVersion: %u\n", cast(unsigned)osvi.dwMajorVersion); + gb_printf("dwMinorVersion: %u\n", cast(unsigned)osvi.dwMinorVersion); + gb_printf("dwBuildNumber: %u\n", cast(unsigned)osvi.dwBuildNumber); + gb_printf("dwPlatformId: %u\n", cast(unsigned)osvi.dwPlatformId); + gb_printf("wServicePackMajor: %u\n", cast(unsigned)osvi.wServicePackMajor); + gb_printf("wServicePackMinor: %u\n", cast(unsigned)osvi.wServicePackMinor); + gb_printf("wSuiteMask: %u\n", cast(unsigned)osvi.wSuiteMask); + gb_printf("wProductType: %u\n", cast(unsigned)osvi.wProductType); } gb_printf("Windows "); @@ -441,18 +441,18 @@ void print_bug_report_help() { TEXT("DisplayVersion"), RRF_RT_REG_SZ, ValueType, - &DisplayVersion, + DisplayVersion, &ValueSize ); if (status == 0x0) { - gb_printf(" (version: %s)", &DisplayVersion); + gb_printf(" (version: %s)", DisplayVersion); } /* Now print build number. */ - gb_printf(", build %d", osvi.dwBuildNumber); + gb_printf(", build %u", cast(unsigned)osvi.dwBuildNumber); ValueSize = sizeof(UBR); status = RegGetValue( @@ -466,7 +466,7 @@ void print_bug_report_help() { ); if (status == 0x0) { - gb_printf(".%d", UBR); + gb_printf(".%u", cast(unsigned)UBR); } gb_printf("\n"); } diff --git a/src/build_settings.cpp b/src/build_settings.cpp index b8d50898d..ccae0fcf0 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -5,7 +5,7 @@ // #if defined(GB_SYSTEM_WINDOWS) -#define DEFAULT_TO_THREADED_CHECKER +// #define DEFAULT_TO_THREADED_CHECKER // #endif enum TargetOsKind { diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 55ad67abf..3f7d2f33d 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -1286,7 +1286,7 @@ void check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *decl, Type *ty using_entities.allocator = heap_allocator(); defer (array_free(&using_entities)); - MUTEX_GUARD_BLOCK(ctx->scope->mutex) { + { if (type->Proc.param_count > 0) { TypeTuple *params = &type->Proc.params->Tuple; for_array(i, params->variables) { @@ -1303,7 +1303,7 @@ 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); - for_array(i, scope->elements.entries) { + MUTEX_GUARD_BLOCK(scope->mutex) for_array(i, scope->elements.entries) { Entity *f = scope->elements.entries[i].value; if (f->kind == Entity_Variable) { Entity *uvar = alloc_entity_using_variable(e, f->token, f->type, nullptr); @@ -1321,11 +1321,10 @@ void check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *decl, Type *ty } } - - for_array(i, using_entities) { + MUTEX_GUARD_BLOCK(ctx->scope->mutex) for_array(i, using_entities) { Entity *e = using_entities[i].e; Entity *uvar = using_entities[i].uvar; - Entity *prev = scope_insert(ctx->scope, uvar); + Entity *prev = scope_insert(ctx->scope, uvar, false); if (prev != nullptr) { error(e->token, "Namespace collision while 'using' procedure argument '%.*s' of: %.*s", LIT(e->token.string), LIT(prev->token.string)); error_line("%.*s != %.*s\n", LIT(uvar->token.string), LIT(prev->token.string)); diff --git a/src/checker.cpp b/src/checker.cpp index 58c71a176..b4c5d0c72 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -446,7 +446,7 @@ Entity *scope_lookup(Scope *s, String const &name) { -Entity *scope_insert_with_name(Scope *s, String const &name, Entity *entity) { +Entity *scope_insert_with_name(Scope *s, String const &name, Entity *entity, bool use_mutex=true) { if (name == "") { return nullptr; } @@ -454,8 +454,8 @@ Entity *scope_insert_with_name(Scope *s, String const &name, Entity *entity) { Entity **found = nullptr; Entity *result = nullptr; - mutex_lock(&s->mutex); - defer (mutex_unlock(&s->mutex)); + if (use_mutex) mutex_lock(&s->mutex); + defer (if (use_mutex) mutex_unlock(&s->mutex)); found = string_map_get(&s->elements, key); @@ -485,9 +485,9 @@ end:; return result; } -Entity *scope_insert(Scope *s, Entity *entity) { +Entity *scope_insert(Scope *s, Entity *entity, bool use_mutex) { String name = entity->token.string; - return scope_insert_with_name(s, name, entity); + return scope_insert_with_name(s, name, entity, use_mutex); } diff --git a/src/checker.hpp b/src/checker.hpp index 74435c1d4..db59ebce7 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -423,7 +423,7 @@ 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); +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); -- cgit v1.2.3 From 7e4067c44ceb21b4ca0ce89e501df1bf9de106b7 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 12 Jan 2022 19:18:54 +0000 Subject: Begin work to move entry point code to Odin itself rather than in C++ side --- core/intrinsics/intrinsics.odin | 5 +++ core/runtime/procs_windows_amd64.odin | 2 +- src/check_builtin.cpp | 6 +++ src/check_decl.cpp | 36 +++++++++-------- src/checker.cpp | 74 +++++++++++++++++++---------------- src/checker.hpp | 3 ++ src/checker_builtin_procs.hpp | 7 +++- src/llvm_backend.cpp | 15 ++++--- src/llvm_backend_proc.cpp | 8 ++++ 9 files changed, 100 insertions(+), 56 deletions(-) (limited to 'src/checker.cpp') diff --git a/core/intrinsics/intrinsics.odin b/core/intrinsics/intrinsics.odin index 2da7a7439..803b04d17 100644 --- a/core/intrinsics/intrinsics.odin +++ b/core/intrinsics/intrinsics.odin @@ -197,3 +197,8 @@ type_field_index_of :: proc($T: typeid, $name: string) -> uintptr --- type_equal_proc :: proc($T: typeid) -> (equal: proc "contextless" (rawptr, rawptr) -> bool) where type_is_comparable(T) --- type_hasher_proc :: proc($T: typeid) -> (hasher: proc "contextless" (data: rawptr, seed: uintptr) -> uintptr) where type_is_comparable(T) --- + + +// Internal compiler use only + +__entry_point :: proc() --- \ No newline at end of file diff --git a/core/runtime/procs_windows_amd64.odin b/core/runtime/procs_windows_amd64.odin index 273bb57b2..e430357be 100644 --- a/core/runtime/procs_windows_amd64.odin +++ b/core/runtime/procs_windows_amd64.odin @@ -22,4 +22,4 @@ windows_trap_type_assertion :: proc "contextless" () -> ! { when ODIN_NO_CRT { @(require) foreign import crt_lib "procs_windows_amd64.asm" -} \ No newline at end of file +} diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index dc8c209c9..82ad6d161 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -219,6 +219,12 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 GB_PANIC("Implement built-in procedure: %.*s", LIT(builtin_name)); break; + case BuiltinProc___entry_point: + operand->mode = Addressing_NoValue; + operand->type = nullptr; + mpmc_enqueue(&c->info->intrinsics_entry_point_usage, call); + break; + case BuiltinProc_DIRECTIVE: { ast_node(bd, BasicDirective, ce->proc); String name = bd->name.string; diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 3f7d2f33d..f9bc17ba4 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -777,21 +777,23 @@ void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) { if (e->pkg != nullptr && e->token.string == "main") { - if (pt->param_count != 0 || - pt->result_count != 0) { - gbString str = type_to_string(proc_type); - error(e->token, "Procedure type of 'main' was expected to be 'proc()', got %s", str); - gb_string_free(str); - } - if (pt->calling_convention != default_calling_convention()) { - error(e->token, "Procedure 'main' cannot have a custom calling convention"); - } - pt->calling_convention = default_calling_convention(); - if (e->pkg->kind == Package_Init) { - if (ctx->info->entry_point != nullptr) { - error(e->token, "Redeclaration of the entry pointer procedure 'main'"); - } else { - ctx->info->entry_point = e; + if (e->pkg->kind != Package_Runtime) { + if (pt->param_count != 0 || + pt->result_count != 0) { + gbString str = type_to_string(proc_type); + error(e->token, "Procedure type of 'main' was expected to be 'proc()', got %s", str); + gb_string_free(str); + } + if (pt->calling_convention != default_calling_convention()) { + error(e->token, "Procedure 'main' cannot have a custom calling convention"); + } + pt->calling_convention = default_calling_convention(); + if (e->pkg->kind == Package_Init) { + if (ctx->info->entry_point != nullptr) { + error(e->token, "Redeclaration of the entry pointer procedure 'main'"); + } else { + ctx->info->entry_point = e; + } } } } @@ -924,7 +926,9 @@ void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) { "\tother at %s", LIT(name), token_pos_to_string(pos)); } else if (name == "main") { - error(d->proc_lit, "The link name 'main' is reserved for internal use"); + if (d->entity->pkg->kind != Package_Runtime) { + error(d->proc_lit, "The link name 'main' is reserved for internal use"); + } } else { string_map_set(fp, key, e); } diff --git a/src/checker.cpp b/src/checker.cpp index b4c5d0c72..42575f88d 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -823,6 +823,7 @@ void init_universal(void) { add_global_bool_constant("ODIN_NO_CRT", bc->no_crt); add_global_bool_constant("ODIN_USE_SEPARATE_MODULES", bc->use_separate_modules); add_global_bool_constant("ODIN_TEST", bc->command_kind == Command_test); + add_global_bool_constant("ODIN_NO_ENTRY_POINT", bc->no_entry_point); // Builtin Procedures @@ -941,6 +942,8 @@ void init_checker_info(CheckerInfo *i) { mutex_init(&i->foreign_mutex); semaphore_init(&i->collect_semaphore); + + mpmc_init(&i->intrinsics_entry_point_usage, a, 1<<10); // just waste some memory here, even if it probably never used } void destroy_checker_info(CheckerInfo *i) { @@ -1228,7 +1231,7 @@ void add_type_and_value(CheckerInfo *i, Ast *expr, AddressingMode mode, Type *ty while (prev_expr != expr) { prev_expr = expr; expr->tav.mode = mode; - if (type != nullptr && expr->tav.type != nullptr && + if (type != nullptr && expr->tav.type != nullptr && is_type_any(type) && is_type_untyped(expr->tav.type)) { // ignore } else { @@ -1424,7 +1427,7 @@ bool could_entity_be_lazy(Entity *e, DeclInfo *d) { return false; } else if (name == "linkage") { return false; - } + } } } } @@ -1704,7 +1707,7 @@ void add_type_info_type_internal(CheckerContext *c, Type *t) { add_type_info_type_internal(c, bt->RelativeSlice.slice_type); add_type_info_type_internal(c, bt->RelativeSlice.base_integer); break; - + case Type_Matrix: add_type_info_type_internal(c, bt->Matrix.elem); break; @@ -1919,7 +1922,7 @@ void add_min_dep_type_info(Checker *c, Type *t) { add_min_dep_type_info(c, bt->RelativeSlice.slice_type); add_min_dep_type_info(c, bt->RelativeSlice.base_integer); break; - + case Type_Matrix: add_min_dep_type_info(c, bt->Matrix.elem); break; @@ -2020,7 +2023,7 @@ void generate_minimum_dependency_set(Checker *c, Entity *start) { str_lit("__init_context"), str_lit("__type_info_of"), str_lit("cstring_to_string"), - str_lit("_cleanup_runtime"), + str_lit("_cleanup_runtime"), // Pseudo-CRT required procedures str_lit("memset"), @@ -2047,7 +2050,7 @@ void generate_minimum_dependency_set(Checker *c, Entity *start) { str_lit("gnu_h2f_ieee"), str_lit("gnu_f2h_ieee"), str_lit("extendhfsf2"), - + // WASM Specific str_lit("__ashlti3"), str_lit("__multi3"), @@ -2119,25 +2122,25 @@ void generate_minimum_dependency_set(Checker *c, Entity *start) { if (e->flags & EntityFlag_Init) { Type *t = base_type(e->type); GB_ASSERT(t->kind == Type_Proc); - + bool is_init = true; - + if (t->Proc.param_count != 0 || t->Proc.result_count != 0) { gbString str = type_to_string(t); error(e->token, "@(init) procedures must have a signature type with no parameters nor results, got %s", str); gb_string_free(str); is_init = false; } - + if ((e->scope->flags & (ScopeFlag_File|ScopeFlag_Pkg)) == 0) { error(e->token, "@(init) procedures must be declared at the file scope"); is_init = false; } - + if (is_init) { add_dependency_to_set(c, e); array_add(&c->info.init_procedures, e); - } + } } break; } @@ -3677,11 +3680,6 @@ void check_single_global_entity(Checker *c, Entity *e, DeclInfo *d) { error(e->token, "'main' is reserved as the entry point procedure in the initial scope"); return; } - } else if (pkg->kind == Package_Runtime) { - if (e->token.string == "main") { - error(e->token, "'main' is reserved as the entry point procedure in the initial scope"); - return; - } } check_entity_decl(ctx, e, d, nullptr); @@ -3841,7 +3839,7 @@ void add_import_dependency_node(Checker *c, Ast *decl, PtrMap generate_import_dependency_graph(Checker *c) { - PtrMap M = {}; + PtrMap M = {}; map_init(&M, heap_allocator(), 2*c->parser->packages.count); defer (map_destroy(&M)); @@ -4121,11 +4119,11 @@ void check_add_foreign_import_decl(CheckerContext *ctx, Ast *decl) { mpmc_enqueue(&ctx->info->required_foreign_imports_through_force_queue, e); add_entity_use(ctx, nullptr, e); } - + if (has_asm_extension(fullpath)) { if (build_context.metrics.arch != TargetArch_amd64 || build_context.metrics.os != TargetOs_windows) { - error(decl, "Assembly files are not yet supported on this platform: %.*s_%.*s", + error(decl, "Assembly files are not yet supported on this platform: %.*s_%.*s", LIT(target_os_names[build_context.metrics.os]), LIT(target_arch_names[build_context.metrics.arch])); } } @@ -4327,7 +4325,7 @@ void check_with_workers(Checker *c, WorkerTaskProc *proc, isize total_count) { if (!build_context.threaded_checker) { worker_count = 0; } - + semaphore_post(&c->info.collect_semaphore, cast(i32)thread_count); if (worker_count == 0) { ThreadProcCheckerSection section_all = {}; @@ -4351,7 +4349,7 @@ void check_with_workers(Checker *c, WorkerTaskProc *proc, isize total_count) { } GB_ASSERT(remaining_count <= 0); - + for (isize i = 0; i < thread_count; i++) { global_thread_pool_add_task(proc, thread_data+i); } @@ -4750,11 +4748,11 @@ bool check_proc_info(Checker *c, ProcInfo *pi, UntypedExprInfoMap *untyped, Proc ctx.decl = pi->decl; ctx.procs_to_check_queue = procs_to_check_queue; GB_ASSERT(procs_to_check_queue != nullptr); - + GB_ASSERT(pi->type->kind == Type_Proc); TypeProc *pt = &pi->type->Proc; String name = pi->token.string; - + if (pt->is_polymorphic && !pt->is_poly_specialized) { Token token = pi->token; if (pi->poly_def_node != nullptr) { @@ -4832,7 +4830,7 @@ void check_unchecked_bodies(Checker *c) { if (pi->body == nullptr) { continue; } - + debugf("unchecked: %.*s\n", LIT(e->token.string)); mpmc_enqueue(&c->procs_to_check_queue, pi); } @@ -4943,14 +4941,14 @@ void check_procedure_bodies(Checker *c) { } if (worker_count == 0) { auto *this_queue = &c->procs_to_check_queue; - + UntypedExprInfoMap untyped = {}; map_init(&untyped, heap_allocator()); - + for (ProcInfo *pi = nullptr; mpmc_dequeue(this_queue, &pi); /**/) { consume_proc_info_queue(c, pi, this_queue, &untyped); } - + map_destroy(&untyped); debugf("Total Procedure Bodies Checked: %td\n", total_bodies_checked.load(std::memory_order_relaxed)); @@ -4994,7 +4992,7 @@ void check_procedure_bodies(Checker *c) { GB_ASSERT(total_queued == original_queue_count); semaphore_post(&c->procs_to_check_semaphore, cast(i32)thread_count); - + for (isize i = 0; i < thread_count; i++) { global_thread_pool_add_task(thread_proc_body, thread_data+i); } @@ -5031,7 +5029,7 @@ void check_deferred_procedures(Checker *c) { Entity *dst = src->Procedure.deferred_procedure.entity; GB_ASSERT(dst != nullptr); GB_ASSERT(dst->kind == Entity_Procedure); - + char const *attribute = "deferred_none"; switch (dst_kind) { case DeferredProcedure_none: @@ -5232,7 +5230,7 @@ GB_COMPARE_PROC(init_procedures_cmp) { cmp = 0; return cmp; } - + if (x->pkg != y->pkg) { isize order_x = x->pkg ? x->pkg->order : 0; isize order_y = y->pkg ? y->pkg->order : 0; @@ -5246,14 +5244,14 @@ GB_COMPARE_PROC(init_procedures_cmp) { String fullpath_y = y->file ? y->file->fullpath : (String{}); String file_x = filename_from_path(fullpath_x); String file_y = filename_from_path(fullpath_y); - + cmp = string_compare(file_x, file_y); if (cmp) { return cmp; } } - + cmp = u64_cmp(x->order_in_src, y->order_in_src); if (cmp) { return cmp; @@ -5433,9 +5431,19 @@ void check_parsed_files(Checker *c) { TIME_SECTION("sanity checks"); GB_ASSERT(c->info.entity_queue.count.load(std::memory_order_relaxed) == 0); GB_ASSERT(c->info.definition_queue.count.load(std::memory_order_relaxed) == 0); - + TIME_SECTION("sort init procedures"); check_sort_init_procedures(c); + if (c->info.intrinsics_entry_point_usage.count > 0) { + TIME_SECTION("check intrinsics.__entry_point usage"); + Ast *node = nullptr; + while (mpmc_dequeue(&c->info.intrinsics_entry_point_usage, &node)) { + if (c->info.entry_point == nullptr && node != nullptr) { + warning(node, "usage of intrinsics.__entry_point will be a no-op"); + } + } + } + TIME_SECTION("type check finish"); } diff --git a/src/checker.hpp b/src/checker.hpp index db59ebce7..9a8753efd 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -338,6 +338,9 @@ struct CheckerInfo { MPMCQueue required_global_variable_queue; MPMCQueue required_foreign_imports_through_force_queue; + MPMCQueue intrinsics_entry_point_usage; + + }; struct CheckerContext { diff --git a/src/checker_builtin_procs.hpp b/src/checker_builtin_procs.hpp index abd9fc6ca..e8f5174c0 100644 --- a/src/checker_builtin_procs.hpp +++ b/src/checker_builtin_procs.hpp @@ -250,6 +250,8 @@ BuiltinProc__type_simple_boolean_end, BuiltinProc__type_end, + BuiltinProc___entry_point, + BuiltinProc_COUNT, }; gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = { @@ -497,6 +499,9 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = { {STR_LIT("type_equal_proc"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("type_hasher_proc"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - + + {STR_LIT(""), 0, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, + + {STR_LIT("__entry_point"), 0, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, }; diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 1a657e47b..b42ea8211 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -873,7 +873,7 @@ lbProcedure *lb_create_main_procedure(lbModule *m, lbProcedure *startup_runtime) } else { if (m->info->entry_point != nullptr) { lbValue entry_point = lb_find_procedure_value_from_entity(m, m->info->entry_point); - lb_emit_call(p, entry_point, {}); + lb_emit_call(p, entry_point, {}, ProcInlining_no_inline); } } @@ -1408,6 +1408,7 @@ void lb_generate_code(lbGenerator *gen) { Entity *entry_point = info->entry_point; bool has_dll_main = false; bool has_win_main = false; + bool already_has_entry_point = false; for_array(i, info->entities) { Entity *e = info->entities[i]; @@ -1425,7 +1426,9 @@ void lb_generate_code(lbGenerator *gen) { if (e->Procedure.is_export || (e->Procedure.link_name.len > 0) || ((e->scope->flags&ScopeFlag_File) && e->Procedure.link_name.len > 0)) { - if (!has_dll_main && name == "DllMain") { + if (name == "main" || name == "DllMain" || name == "WinMain" || name == "mainCRTStartup") { + already_has_entry_point = true; + } else if (!has_dll_main && name == "DllMain") { has_dll_main = true; } else if (!has_win_main && name == "WinMain") { has_win_main = true; @@ -1643,9 +1646,11 @@ void lb_generate_code(lbGenerator *gen) { } - if (!(build_context.build_mode == BuildMode_DynamicLibrary && !has_dll_main)) { - TIME_SECTION("LLVM main"); - lb_create_main_procedure(default_module, startup_runtime); + if (!already_has_entry_point) { + if (!(build_context.build_mode == BuildMode_DynamicLibrary && !has_dll_main)) { + TIME_SECTION("LLVM main"); + lb_create_main_procedure(default_module, startup_runtime); + } } for_array(j, gen->modules.entries) { diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index 50aa5f6db..10b8a093f 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -1965,6 +1965,14 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, return res; } + case BuiltinProc___entry_point: + if (p->module->info->entry_point) { + lbValue entry_point = lb_find_procedure_value_from_entity(p->module, p->module->info->entry_point); + GB_ASSERT(entry_point.value != nullptr); + lb_emit_call(p, entry_point, {}); + } + return {}; + case BuiltinProc_syscall: { unsigned arg_count = cast(unsigned)ce->args.count; -- cgit v1.2.3 From fb0a3ab7c14d4bc3b821cef723ec6ea3e956c956 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 12 Jan 2022 20:07:17 +0000 Subject: Correct linkage for entry point procedures on Windows --- src/checker.cpp | 8 +++++++- src/llvm_backend.cpp | 23 +++++++++++------------ src/llvm_backend_proc.cpp | 2 +- 3 files changed, 19 insertions(+), 14 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index 42575f88d..f261c8f4a 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -2113,11 +2113,15 @@ void generate_minimum_dependency_set(Checker *c, Entity *start) { case Entity_Variable: if (e->Variable.is_export) { add_dependency_to_set(c, e); + } else if (e->flags & EntityFlag_Require) { + add_dependency_to_set(c, e); } break; case Entity_Procedure: if (e->Procedure.is_export) { add_dependency_to_set(c, e); + } else if (e->flags & EntityFlag_Require) { + add_dependency_to_set(c, e); } if (e->flags & EntityFlag_Init) { Type *t = base_type(e->type); @@ -5440,7 +5444,9 @@ void check_parsed_files(Checker *c) { Ast *node = nullptr; while (mpmc_dequeue(&c->info.intrinsics_entry_point_usage, &node)) { if (c->info.entry_point == nullptr && node != nullptr) { - warning(node, "usage of intrinsics.__entry_point will be a no-op"); + if (node->file()->pkg->kind != Package_Runtime) { + warning(node, "usage of intrinsics.__entry_point will be a no-op"); + } } } } diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 0b4c674ac..1c3cf86ac 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -1405,7 +1405,6 @@ void lb_generate_code(lbGenerator *gen) { isize global_variable_max_count = 0; - Entity *entry_point = info->entry_point; bool already_has_entry_point = false; for_array(i, info->entities) { @@ -1416,14 +1415,17 @@ void lb_generate_code(lbGenerator *gen) { global_variable_max_count++; } else if (e->kind == Entity_Procedure) { if ((e->scope->flags&ScopeFlag_Init) && name == "main") { - GB_ASSERT(e == entry_point); - // entry_point = e; + GB_ASSERT(e == info->entry_point); } if (e->Procedure.is_export || (e->Procedure.link_name.len > 0) || ((e->scope->flags&ScopeFlag_File) && e->Procedure.link_name.len > 0)) { String link_name = e->Procedure.link_name; - if (link_name == "main" || link_name == "DllMain" || link_name == "WinMain" || link_name == "mainCRTStartup") { + if (link_name == "main" || + link_name == "DllMain" || + link_name == "WinMain" || + link_name == "wWinMain" || + link_name == "mainCRTStartup") { already_has_entry_point = true; } } @@ -1562,6 +1564,11 @@ void lb_generate_code(lbGenerator *gen) { } } + TIME_SECTION("LLVM Runtime Type Information Creation"); + lbProcedure *startup_type_info = lb_create_startup_type_info(default_module); + + TIME_SECTION("LLVM Runtime Startup Creation (Global Variables)"); + lbProcedure *startup_runtime = lb_create_startup_runtime(default_module, startup_type_info, global_variables); TIME_SECTION("LLVM Global Procedures and Types"); for_array(i, info->entities) { @@ -1621,14 +1628,6 @@ void lb_generate_code(lbGenerator *gen) { } } - - TIME_SECTION("LLVM Runtime Type Information Creation"); - lbProcedure *startup_type_info = lb_create_startup_type_info(default_module); - - TIME_SECTION("LLVM Runtime Startup Creation (Global Variables)"); - lbProcedure *startup_runtime = lb_create_startup_runtime(default_module, startup_type_info, global_variables); - - TIME_SECTION("LLVM Procedure Generation"); for_array(j, gen->modules.entries) { lbModule *m = gen->modules.entries[j].value; diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index 10b8a093f..c52572588 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -304,7 +304,7 @@ lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool ignore_body) lbProcedure *lb_create_dummy_procedure(lbModule *m, String link_name, Type *type) { { lbValue *found = string_map_get(&m->members, link_name); - GB_ASSERT(found == nullptr); + GB_ASSERT_MSG(found == nullptr, "failed to create dummy procedure for: %.*s", LIT(link_name)); } lbProcedure *p = gb_alloc_item(permanent_allocator(), lbProcedure); -- cgit v1.2.3 From 6c4867081985a8dd1cccb3e5c503d72807e4ee87 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 15 Jan 2022 17:34:35 +0000 Subject: Make `ODIN_BUILD_MODE` a enum type --- core/runtime/core.odin | 13 +++++ core/runtime/entry_unix.odin | 2 +- core/runtime/entry_windows.odin | 2 +- core/runtime/internal.odin | 2 +- src/build_settings.cpp | 23 ++------- src/check_expr.cpp | 112 ++++++++++++++++++++++------------------ src/checker.cpp | 64 ++++++++++++++++++++++- 7 files changed, 144 insertions(+), 74 deletions(-) (limited to 'src/checker.cpp') diff --git a/core/runtime/core.odin b/core/runtime/core.odin index be30eef02..91b6bf5ca 100644 --- a/core/runtime/core.odin +++ b/core/runtime/core.odin @@ -386,6 +386,19 @@ Raw_Cstring :: struct { } +/* + // Defined internally by the compiler + Odin_Build_Mode_Type :: enum int { + Executable, + Dynamic, + Object, + Assembly, + LLVM_IR, + } +*/ +Odin_Build_Mode_Type :: type_of(ODIN_BUILD_MODE) + + ///////////////////////////// // Init Startup Procedures // ///////////////////////////// diff --git a/core/runtime/entry_unix.odin b/core/runtime/entry_unix.odin index 38116c0f9..67d2cbcb7 100644 --- a/core/runtime/entry_unix.odin +++ b/core/runtime/entry_unix.odin @@ -4,7 +4,7 @@ package runtime import "core:intrinsics" -when ODIN_BUILD_MODE == "dynamic" { +when ODIN_BUILD_MODE == .Dynamic { @(link_name="_odin_entry_point", linkage="strong", require, link_section=".init") _odin_entry_point :: proc "c" () { context = default_context() diff --git a/core/runtime/entry_windows.odin b/core/runtime/entry_windows.odin index ef8b0c529..97a5bebe6 100644 --- a/core/runtime/entry_windows.odin +++ b/core/runtime/entry_windows.odin @@ -4,7 +4,7 @@ package runtime import "core:intrinsics" -when ODIN_BUILD_MODE == "dynamic" { +when ODIN_BUILD_MODE == .Dynamic { @(link_name="DllMain", linkage="strong", require) DllMain :: proc "stdcall" (hinstDLL: rawptr, fdwReason: u32, lpReserved: rawptr) -> b32 { context = default_context() diff --git a/core/runtime/internal.odin b/core/runtime/internal.odin index 6498c4db7..7b283a132 100644 --- a/core/runtime/internal.odin +++ b/core/runtime/internal.odin @@ -8,7 +8,7 @@ IS_WASM :: ODIN_ARCH == "wasm32" || ODIN_ARCH == "wasm64" @(private) RUNTIME_LINKAGE :: "strong" when ( (ODIN_USE_SEPARATE_MODULES || - ODIN_BUILD_MODE == "dynamic" || + ODIN_BUILD_MODE == .Dynamic || !ODIN_NO_CRT) && !IS_WASM) else "internal" RUNTIME_REQUIRE :: true diff --git a/src/build_settings.cpp b/src/build_settings.cpp index ccae0fcf0..bafa93042 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -119,6 +119,8 @@ enum BuildModeKind { BuildMode_Object, BuildMode_Assembly, BuildMode_LLVM_IR, + + BuildMode_COUNT, }; enum CommandKind : u32 { @@ -172,10 +174,9 @@ struct BuildContext { String ODIN_VENDOR; // compiler vendor String ODIN_VERSION; // compiler version String ODIN_ROOT; // Odin ROOT - String ODIN_BUILD_MODE; bool ODIN_DEBUG; // Odin in debug mode bool ODIN_DISABLE_ASSERT; // Whether the default 'assert' et al is disabled in code or not - bool ODIN_DEFAULT_TO_NIL_ALLOCATOR; // Whether the default allocator is a "nil" allocator or not (i.e. it does nothing) +bool ODIN_DEFAULT_TO_NIL_ALLOCATOR; // Whether the default allocator is a "nil" allocator or not (i.e. it does nothing) TargetEndianKind endian_kind; @@ -855,24 +856,6 @@ void init_build_context(TargetMetrics *cross_target) { bc->ODIN_VENDOR = str_lit("odin"); bc->ODIN_VERSION = ODIN_VERSION; bc->ODIN_ROOT = odin_root_dir(); - switch (bc->build_mode) { - default: - case BuildMode_Executable: - bc->ODIN_BUILD_MODE = str_lit("executable"); - break; - case BuildMode_DynamicLibrary: - bc->ODIN_BUILD_MODE = str_lit("dynamic"); - break; - case BuildMode_Object: - bc->ODIN_BUILD_MODE = str_lit("object"); - break; - case BuildMode_Assembly: - bc->ODIN_BUILD_MODE = str_lit("assembly"); - break; - case BuildMode_LLVM_IR: - bc->ODIN_BUILD_MODE = str_lit("llvm-ir"); - break; - } bc->copy_file_contents = true; diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 1162cefee..8667d8734 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -119,6 +119,58 @@ 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); void check_or_return_split_types(CheckerContext *c, Operand *x, String const &name, Type **left_type_, Type **right_type_); + +void check_did_you_mean_print(DidYouMeanAnswers *d, char const *prefix = "") { + auto results = did_you_mean_results(d); + if (results.count != 0) { + error_line("\tSuggestion: Did you mean?\n"); + for_array(i, results) { + String const &target = results[i].target; + error_line("\t\t%s%.*s\n", prefix, LIT(target)); + // error_line("\t\t%.*s %td\n", LIT(target), results[i].distance); + } + } +} + +void check_did_you_mean_type(String const &name, Array const &fields, char const *prefix = "") { + ERROR_BLOCK(); + + DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), fields.count, name); + defer (did_you_mean_destroy(&d)); + + for_array(i, fields) { + did_you_mean_append(&d, fields[i]->token.string); + } + check_did_you_mean_print(&d, prefix); +} + +void check_did_you_mean_type(String const &name, Slice const &fields, char const *prefix = "") { + ERROR_BLOCK(); + + DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), fields.count, name); + defer (did_you_mean_destroy(&d)); + + for_array(i, fields) { + did_you_mean_append(&d, fields[i]->token.string); + } + check_did_you_mean_print(&d, prefix); +} + +void check_did_you_mean_scope(String const &name, Scope *scope, char const *prefix = "") { + ERROR_BLOCK(); + + DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), scope->elements.entries.count, name); + defer (did_you_mean_destroy(&d)); + + mutex_lock(&scope->mutex); + for_array(i, scope->elements.entries) { + Entity *e = scope->elements.entries[i].value; + did_you_mean_append(&d, e->token.string); + } + mutex_unlock(&scope->mutex); + check_did_you_mean_print(&d, prefix); +} + Entity *entity_from_expr(Ast *expr) { expr = unparen_expr(expr); switch (expr->kind) { @@ -3361,7 +3413,17 @@ void convert_untyped_error(CheckerContext *c, Operand *operand, Type *target_typ } } } + ERROR_BLOCK(); + error(operand->expr, "Cannot convert untyped value '%s' to '%s' from '%s'%s", expr_str, type_str, from_type_str, extra_text); + if (operand->value.kind == ExactValue_String) { + String key = operand->value.value_string; + if (is_type_string(operand->type) && is_type_enum(target_type)) { + gb_printf_err("HERE!\n"); + Type *et = base_type(target_type); + check_did_you_mean_type(key, et->Enum.fields, "."); + } + } gb_string_free(from_type_str); gb_string_free(type_str); @@ -3979,56 +4041,6 @@ ExactValue get_constant_field(CheckerContext *c, Operand const *operand, Selecti if (success_) *success_ = true; return empty_exact_value; } -void check_did_you_mean_print(DidYouMeanAnswers *d) { - auto results = did_you_mean_results(d); - if (results.count != 0) { - error_line("\tSuggestion: Did you mean?\n"); - for_array(i, results) { - String const &target = results[i].target; - error_line("\t\t%.*s\n", LIT(target)); - // error_line("\t\t%.*s %td\n", LIT(target), results[i].distance); - } - } -} - -void check_did_you_mean_type(String const &name, Array const &fields) { - ERROR_BLOCK(); - - DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), fields.count, name); - defer (did_you_mean_destroy(&d)); - - for_array(i, fields) { - did_you_mean_append(&d, fields[i]->token.string); - } - check_did_you_mean_print(&d); -} - -void check_did_you_mean_type(String const &name, Slice const &fields) { - ERROR_BLOCK(); - - DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), fields.count, name); - defer (did_you_mean_destroy(&d)); - - for_array(i, fields) { - did_you_mean_append(&d, fields[i]->token.string); - } - check_did_you_mean_print(&d); -} - -void check_did_you_mean_scope(String const &name, Scope *scope) { - ERROR_BLOCK(); - - DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), scope->elements.entries.count, name); - defer (did_you_mean_destroy(&d)); - - mutex_lock(&scope->mutex); - for_array(i, scope->elements.entries) { - Entity *e = scope->elements.entries[i].value; - did_you_mean_append(&d, e->token.string); - } - mutex_unlock(&scope->mutex); - check_did_you_mean_print(&d); -} Type *determine_swizzle_array_type(Type *original_type, Type *type_hint, isize new_count) { Type *array_type = base_type(type_deref(original_type)); diff --git a/src/checker.cpp b/src/checker.cpp index f261c8f4a..c3dcd1d11 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -780,6 +780,54 @@ AstPackage *create_builtin_package(char const *name) { return pkg; } +struct GlobalEnumValue { + char const *name; + i64 value; +}; + +Slice add_global_enum_type(String const &type_name, GlobalEnumValue *values, isize value_count) { + Scope *scope = create_scope(nullptr, builtin_pkg->scope); + Entity *e = alloc_entity_type_name(scope, make_token_ident(type_name), nullptr, EntityState_Resolved); + + Type *enum_type = alloc_type_enum(); + Type *named_type = alloc_type_named(type_name, enum_type, e); + set_base_type(named_type, enum_type); + enum_type->Enum.base_type = t_int; + enum_type->Enum.scope = scope; + + auto fields = array_make(permanent_allocator(), value_count); + for (isize i = 0; i < value_count; i++) { + i64 value = values[i].value; + Entity *e = alloc_entity_constant(scope, make_token_ident(values[i].name), named_type, exact_value_i64(value)); + e->flags |= EntityFlag_Visited; + e->state = EntityState_Resolved; + fields[i] = e; + + Entity *ie = scope_insert(scope, e); + GB_ASSERT(ie == nullptr); + } + + + enum_type->Enum.fields = fields; + enum_type->Enum.min_value_index = 0; + enum_type->Enum.max_value_index = value_count-1; + enum_type->Enum.min_value = &enum_type->Enum.fields[enum_type->Enum.min_value_index]->Constant.value; + enum_type->Enum.max_value = &enum_type->Enum.fields[enum_type->Enum.max_value_index]->Constant.value; + + return slice_from_array(fields); +} +void add_global_enum_constant(Slice const &fields, char const *name, i64 value) { + for (Entity *field : fields) { + GB_ASSERT(field->kind == Entity_Constant); + if (value == exact_value_to_i64(field->Constant.value)) { + add_global_constant(name, field->type, field->Constant.value); + return; + } + } + GB_PANIC("Unfound enum value for global constant: %s %lld", name, cast(long long)value); +} + + void init_universal(void) { BuildContext *bc = &build_context; @@ -815,7 +863,21 @@ void init_universal(void) { add_global_string_constant("ODIN_VERSION", bc->ODIN_VERSION); add_global_string_constant("ODIN_ROOT", bc->ODIN_ROOT); - add_global_string_constant("ODIN_BUILD_MODE", bc->ODIN_BUILD_MODE); + { + GlobalEnumValue values[BuildMode_COUNT] = { + {"Executable", BuildMode_Executable}, + {"Dynamic", BuildMode_DynamicLibrary}, + {"Object", BuildMode_Object}, + {"Assembly", BuildMode_Assembly}, + {"LLVM_IR", BuildMode_LLVM_IR}, + }; + + auto fields = add_global_enum_type(str_lit("Odin_Build_Mode_Type"), values, gb_count_of(values)); + add_global_enum_constant(fields, "ODIN_BUILD_MODE", bc->build_mode); + } + + // add_global_string_constant("ODIN_BUILD_MODE", bc->ODIN_BUILD_MODE); + add_global_bool_constant("ODIN_DEBUG", bc->ODIN_DEBUG); add_global_bool_constant("ODIN_DISABLE_ASSERT", bc->ODIN_DISABLE_ASSERT); add_global_bool_constant("ODIN_DEFAULT_TO_NIL_ALLOCATOR", bc->ODIN_DEFAULT_TO_NIL_ALLOCATOR); -- cgit v1.2.3 From f0529535e02ab175bca3f7ff8c3bc2112d949236 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 15 Jan 2022 17:53:18 +0000 Subject: `ODIN_ENDIAN` changed to an enum constant; `ODIN_ENUM_STRING` is the new string version of the old constant --- core/crypto/_sha3/_sha3.odin | 4 ++-- core/crypto/haval/haval.odin | 2 +- core/encoding/json/marshal.odin | 4 ++-- core/fmt/fmt.odin | 4 ++-- core/hash/xxhash/streaming.odin | 2 +- core/image/png/example.odin | 2 +- core/image/png/png.odin | 2 +- core/math/bits/bits.odin | 32 ++++++++++++++++---------------- core/runtime/core.odin | 10 ++++++++++ core/runtime/udivmod128.odin | 2 +- src/build_settings.cpp | 20 +++++++++----------- src/checker.cpp | 15 +++++++++++++-- vendor/sdl2/sdl_audio.odin | 2 +- vendor/sdl2/sdl_pixels.odin | 8 ++++---- 14 files changed, 64 insertions(+), 45 deletions(-) (limited to 'src/checker.cpp') diff --git a/core/crypto/_sha3/_sha3.odin b/core/crypto/_sha3/_sha3.odin index 76e09bf24..9846aca42 100644 --- a/core/crypto/_sha3/_sha3.odin +++ b/core/crypto/_sha3/_sha3.odin @@ -52,7 +52,7 @@ keccakf :: proc "contextless" (st: ^[25]u64) { t: u64 = --- bc: [5]u64 = --- - when ODIN_ENDIAN != "little" { + when ODIN_ENDIAN != .Little { v: uintptr = --- for i = 0; i < 25; i += 1 { v := uintptr(&st[i]) @@ -98,7 +98,7 @@ keccakf :: proc "contextless" (st: ^[25]u64) { st[0] ~= keccakf_rndc[r] } - when ODIN_ENDIAN != "little" { + when ODIN_ENDIAN != .Little { for i = 0; i < 25; i += 1 { v = uintptr(&st[i]) t = st[i] diff --git a/core/crypto/haval/haval.odin b/core/crypto/haval/haval.odin index f95ea344d..442a348e9 100644 --- a/core/crypto/haval/haval.odin +++ b/core/crypto/haval/haval.odin @@ -1332,7 +1332,7 @@ update :: proc(ctx: ^Haval_Context, data: []byte) { } ctx.count[1] += str_len >> 29 - when ODIN_ENDIAN == "little" { + when ODIN_ENDIAN == .Little { if rmd_len + str_len >= 128 { copy(util.slice_to_bytes(ctx.block[:])[rmd_len:], data[:fill_len]) block(ctx, ctx.rounds) diff --git a/core/encoding/json/marshal.odin b/core/encoding/json/marshal.odin index adbcb95be..aa1c1559c 100644 --- a/core/encoding/json/marshal.odin +++ b/core/encoding/json/marshal.odin @@ -285,8 +285,8 @@ marshal_to_writer :: proc(w: io.Writer, v: any) -> (err: Marshal_Error) { case runtime.Type_Info_Integer: switch info.endianness { case .Platform: return false - case .Little: return ODIN_ENDIAN != "little" - case .Big: return ODIN_ENDIAN != "big" + case .Little: return ODIN_ENDIAN != .Little + case .Big: return ODIN_ENDIAN != .Big } } return false diff --git a/core/fmt/fmt.odin b/core/fmt/fmt.odin index a9ff6ca47..2cc192c12 100644 --- a/core/fmt/fmt.odin +++ b/core/fmt/fmt.odin @@ -1092,8 +1092,8 @@ fmt_bit_set :: proc(fi: ^Info, v: any, name: string = "") { case runtime.Type_Info_Integer: switch info.endianness { case .Platform: return false - case .Little: return ODIN_ENDIAN != "little" - case .Big: return ODIN_ENDIAN != "big" + case .Little: return ODIN_ENDIAN != .Little + case .Big: return ODIN_ENDIAN != .Big } } return false diff --git a/core/hash/xxhash/streaming.odin b/core/hash/xxhash/streaming.odin index 737e37eae..d6df1089f 100644 --- a/core/hash/xxhash/streaming.odin +++ b/core/hash/xxhash/streaming.odin @@ -96,7 +96,7 @@ XXH3_128_canonical_from_hash :: proc(hash: XXH128_hash_t) -> (canonical: XXH128_ #assert(size_of(XXH128_canonical) == size_of(XXH128_hash_t)) t := hash - when ODIN_ENDIAN == "little" { + when ODIN_ENDIAN == .Little { t.high = byte_swap(t.high) t.low = byte_swap(t.low) } diff --git a/core/image/png/example.odin b/core/image/png/example.odin index 5e7dca4c8..f4eb5128e 100644 --- a/core/image/png/example.odin +++ b/core/image/png/example.odin @@ -189,7 +189,7 @@ write_image_as_ppm :: proc(filename: string, image: ^image.Image) -> (success: b img := image // PBM 16-bit images are big endian - when ODIN_ENDIAN == "little" { + when ODIN_ENDIAN == .Little { if img.depth == 16 { // The pixel components are in Big Endian. Let's byteswap back. input := mem.slice_data_cast([]u16, img.pixels.buf[:]) diff --git a/core/image/png/png.odin b/core/image/png/png.odin index f77bf7519..da76a4588 100644 --- a/core/image/png/png.odin +++ b/core/image/png/png.odin @@ -1611,7 +1611,7 @@ defilter :: proc(img: ^Image, filter_bytes: ^bytes.Buffer, header: ^image.PNG_IH } } } - when ODIN_ENDIAN == "little" { + when ODIN_ENDIAN == .Little { if img.depth == 16 { // The pixel components are in Big Endian. Let's byteswap. input := mem.slice_data_cast([]u16be, img.pixels.buf[:]) diff --git a/core/math/bits/bits.odin b/core/math/bits/bits.odin index bff984cc7..850e8038a 100644 --- a/core/math/bits/bits.odin +++ b/core/math/bits/bits.odin @@ -69,29 +69,29 @@ rotate_left :: proc(x: uint, k: int) -> uint { } from_be_u8 :: proc(i: u8) -> u8 { return i } -from_be_u16 :: proc(i: u16) -> u16 { when ODIN_ENDIAN == "big" { return i } else { return byte_swap(i) } } -from_be_u32 :: proc(i: u32) -> u32 { when ODIN_ENDIAN == "big" { return i } else { return byte_swap(i) } } -from_be_u64 :: proc(i: u64) -> u64 { when ODIN_ENDIAN == "big" { return i } else { return byte_swap(i) } } -from_be_uint :: proc(i: uint) -> uint { when ODIN_ENDIAN == "big" { return i } else { return byte_swap(i) } } +from_be_u16 :: proc(i: u16) -> u16 { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } } +from_be_u32 :: proc(i: u32) -> u32 { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } } +from_be_u64 :: proc(i: u64) -> u64 { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } } +from_be_uint :: proc(i: uint) -> uint { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } } from_le_u8 :: proc(i: u8) -> u8 { return i } -from_le_u16 :: proc(i: u16) -> u16 { when ODIN_ENDIAN == "little" { return i } else { return byte_swap(i) } } -from_le_u32 :: proc(i: u32) -> u32 { when ODIN_ENDIAN == "little" { return i } else { return byte_swap(i) } } -from_le_u64 :: proc(i: u64) -> u64 { when ODIN_ENDIAN == "little" { return i } else { return byte_swap(i) } } -from_le_uint :: proc(i: uint) -> uint { when ODIN_ENDIAN == "little" { return i } else { return byte_swap(i) } } +from_le_u16 :: proc(i: u16) -> u16 { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } } +from_le_u32 :: proc(i: u32) -> u32 { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } } +from_le_u64 :: proc(i: u64) -> u64 { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } } +from_le_uint :: proc(i: uint) -> uint { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } } to_be_u8 :: proc(i: u8) -> u8 { return i } -to_be_u16 :: proc(i: u16) -> u16 { when ODIN_ENDIAN == "big" { return i } else { return byte_swap(i) } } -to_be_u32 :: proc(i: u32) -> u32 { when ODIN_ENDIAN == "big" { return i } else { return byte_swap(i) } } -to_be_u64 :: proc(i: u64) -> u64 { when ODIN_ENDIAN == "big" { return i } else { return byte_swap(i) } } -to_be_uint :: proc(i: uint) -> uint { when ODIN_ENDIAN == "big" { return i } else { return byte_swap(i) } } +to_be_u16 :: proc(i: u16) -> u16 { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } } +to_be_u32 :: proc(i: u32) -> u32 { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } } +to_be_u64 :: proc(i: u64) -> u64 { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } } +to_be_uint :: proc(i: uint) -> uint { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } } to_le_u8 :: proc(i: u8) -> u8 { return i } -to_le_u16 :: proc(i: u16) -> u16 { when ODIN_ENDIAN == "little" { return i } else { return byte_swap(i) } } -to_le_u32 :: proc(i: u32) -> u32 { when ODIN_ENDIAN == "little" { return i } else { return byte_swap(i) } } -to_le_u64 :: proc(i: u64) -> u64 { when ODIN_ENDIAN == "little" { return i } else { return byte_swap(i) } } -to_le_uint :: proc(i: uint) -> uint { when ODIN_ENDIAN == "little" { return i } else { return byte_swap(i) } } +to_le_u16 :: proc(i: u16) -> u16 { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } } +to_le_u32 :: proc(i: u32) -> u32 { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } } +to_le_u64 :: proc(i: u64) -> u64 { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } } +to_le_uint :: proc(i: uint) -> uint { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } } diff --git a/core/runtime/core.odin b/core/runtime/core.odin index 91b6bf5ca..424650828 100644 --- a/core/runtime/core.odin +++ b/core/runtime/core.odin @@ -398,6 +398,16 @@ Raw_Cstring :: struct { */ Odin_Build_Mode_Type :: type_of(ODIN_BUILD_MODE) +/* + // Defined internally by the compiler + Odin_Endian_Type :: enum int { + Unknown, + Little, + Big, + } +*/ +Odin_Endian_Type :: type_of(ODIN_ENDIAN) + ///////////////////////////// // Init Startup Procedures // diff --git a/core/runtime/udivmod128.odin b/core/runtime/udivmod128.odin index 1fd1b5f84..87ef73c2c 100644 --- a/core/runtime/udivmod128.odin +++ b/core/runtime/udivmod128.odin @@ -11,7 +11,7 @@ udivmod128 :: proc "c" (a, b: u128, rem: ^u128) -> u128 { q, r: [2]u64 sr: u32 = 0 - low :: 1 when ODIN_ENDIAN == "big" else 0 + low :: 1 when ODIN_ENDIAN == .Big else 0 high :: 1 - low U64_BITS :: 8*size_of(u64) U128_BITS :: 8*size_of(u128) diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 5e4534517..b4a934ec8 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -170,7 +170,6 @@ struct BuildContext { // Constants String ODIN_OS; // target operating system String ODIN_ARCH; // target architecture - String ODIN_ENDIAN; // target endian String ODIN_VENDOR; // compiler vendor String ODIN_VERSION; // compiler version String ODIN_ROOT; // Odin ROOT @@ -269,7 +268,7 @@ bool global_ignore_warnings(void) { } -gb_global TargetMetrics target_windows_i386 = { +gb_global TargetMetrics target_windows_386 = { TargetOs_windows, TargetArch_i386, 4, @@ -285,7 +284,7 @@ gb_global TargetMetrics target_windows_amd64 = { str_lit("e-m:w-i64:64-f80:128-n8:16:32:64-S128"), }; -gb_global TargetMetrics target_linux_i386 = { +gb_global TargetMetrics target_linux_386 = { TargetOs_linux, TargetArch_i386, 4, @@ -328,7 +327,7 @@ gb_global TargetMetrics target_darwin_arm64 = { str_lit("e-m:o-i64:64-i128:128-n32:64-S128"), // TODO(bill): Is this correct? }; -gb_global TargetMetrics target_freebsd_i386 = { +gb_global TargetMetrics target_freebsd_386 = { TargetOs_freebsd, TargetArch_i386, 4, @@ -401,12 +400,12 @@ gb_global NamedTargetMetrics named_targets[] = { { str_lit("darwin_amd64"), &target_darwin_amd64 }, { str_lit("darwin_arm64"), &target_darwin_arm64 }, { str_lit("essence_amd64"), &target_essence_amd64 }, - { str_lit("linux_i386"), &target_linux_i386 }, + { str_lit("linux_386"), &target_linux_386 }, { str_lit("linux_amd64"), &target_linux_amd64 }, { str_lit("linux_arm64"), &target_linux_arm64 }, - { str_lit("windows_i386"), &target_windows_i386 }, + { str_lit("windows_386"), &target_windows_386 }, { str_lit("windows_amd64"), &target_windows_amd64 }, - { str_lit("freebsd_i386"), &target_freebsd_i386 }, + { str_lit("freebsd_386"), &target_freebsd_386 }, { str_lit("freebsd_amd64"), &target_freebsd_amd64 }, { str_lit("freestanding_wasm32"), &target_freestanding_wasm32 }, { str_lit("wasi_wasm32"), &target_wasi_wasm32 }, @@ -879,13 +878,13 @@ void init_build_context(TargetMetrics *cross_target) { #endif #else #if defined(GB_SYSTEM_WINDOWS) - metrics = &target_windows_i386; + metrics = &target_windows_386; #elif defined(GB_SYSTEM_OSX) #error "Build Error: Unsupported architecture" #elif defined(GB_SYSTEM_FREEBSD) - metrics = &target_freebsd_i386; + metrics = &target_freebsd_386; #else - metrics = &target_linux_i386; + metrics = &target_linux_386; #endif #endif @@ -904,7 +903,6 @@ void init_build_context(TargetMetrics *cross_target) { bc->metrics = *metrics; bc->ODIN_OS = target_os_names[metrics->os]; bc->ODIN_ARCH = target_arch_names[metrics->arch]; - bc->ODIN_ENDIAN = target_endian_names[target_endians[metrics->arch]]; bc->endian_kind = target_endians[metrics->arch]; bc->word_size = metrics->word_size; bc->max_align = metrics->max_align; diff --git a/src/checker.cpp b/src/checker.cpp index c3dcd1d11..ddb73d33e 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -858,7 +858,6 @@ void init_universal(void) { // TODO(bill): Set through flags in the compiler add_global_string_constant("ODIN_OS", bc->ODIN_OS); add_global_string_constant("ODIN_ARCH", bc->ODIN_ARCH); - add_global_string_constant("ODIN_ENDIAN", bc->ODIN_ENDIAN); add_global_string_constant("ODIN_VENDOR", bc->ODIN_VENDOR); add_global_string_constant("ODIN_VERSION", bc->ODIN_VERSION); add_global_string_constant("ODIN_ROOT", bc->ODIN_ROOT); @@ -876,7 +875,19 @@ void init_universal(void) { add_global_enum_constant(fields, "ODIN_BUILD_MODE", bc->build_mode); } - // add_global_string_constant("ODIN_BUILD_MODE", bc->ODIN_BUILD_MODE); + add_global_string_constant("ODIN_ENDIAN_STRING", target_endian_names[target_endians[bc->metrics.arch]]); + { + GlobalEnumValue values[TargetEndian_COUNT] = { + {"Unknown", TargetEndian_Invalid}, + + {"Little", TargetEndian_Little}, + {"Big", TargetEndian_Big}, + }; + + auto fields = add_global_enum_type(str_lit("Odin_Endian_Type"), values, gb_count_of(values)); + add_global_enum_constant(fields, "ODIN_ENDIAN", target_endians[bc->metrics.arch]); + } + add_global_bool_constant("ODIN_DEBUG", bc->ODIN_DEBUG); add_global_bool_constant("ODIN_DISABLE_ASSERT", bc->ODIN_DISABLE_ASSERT); diff --git a/vendor/sdl2/sdl_audio.odin b/vendor/sdl2/sdl_audio.odin index e108e31c6..2c5b7fedb 100644 --- a/vendor/sdl2/sdl_audio.odin +++ b/vendor/sdl2/sdl_audio.odin @@ -59,7 +59,7 @@ AUDIO_F32LSB :: 0x8120 /**< 32-bit floating point samples */ AUDIO_F32MSB :: 0x9120 /**< As above, but big-endian byte order */ AUDIO_F32 :: AUDIO_F32LSB -when ODIN_ENDIAN == "little" { +when ODIN_ENDIAN == .Little { AUDIO_U16SYS :: AUDIO_U16LSB AUDIO_S16SYS :: AUDIO_S16LSB AUDIO_S32SYS :: AUDIO_S32LSB diff --git a/vendor/sdl2/sdl_pixels.odin b/vendor/sdl2/sdl_pixels.odin index a8503c621..22f6db440 100644 --- a/vendor/sdl2/sdl_pixels.odin +++ b/vendor/sdl2/sdl_pixels.odin @@ -156,10 +156,10 @@ PixelFormatEnum :: enum u32 { ARGB2101010 = 1<<28 | PIXELTYPE_PACKED32<<24 | PACKEDORDER_ARGB<<20 | PACKEDLAYOUT_2101010<<16 | 32<<8 | 4<<0, /* Aliases for RGBA byte arrays of color data, for the current platform */ - RGBA32 = RGBA8888 when ODIN_ENDIAN == "big" else ABGR8888, - ARGB32 = ARGB8888 when ODIN_ENDIAN == "big" else BGRA8888, - BGRA32 = BGRA8888 when ODIN_ENDIAN == "big" else ARGB8888, - ABGR32 = ABGR8888 when ODIN_ENDIAN == "big" else RGBA8888, + RGBA32 = RGBA8888 when ODIN_ENDIAN == .Big else ABGR8888, + ARGB32 = ARGB8888 when ODIN_ENDIAN == .Big else BGRA8888, + BGRA32 = BGRA8888 when ODIN_ENDIAN == .Big else ARGB8888, + ABGR32 = ABGR8888 when ODIN_ENDIAN == .Big else RGBA8888, YV12 = /**< Planar mode: Y + V + U (3 planes) */ 'Y'<<24 | 'V'<<16 | '1'<<8 | '2'<<0, -- cgit v1.2.3 From cafb6e5587d4d3f5211b945bcb9d949a3980aa89 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 17 Jan 2022 21:33:20 +0000 Subject: Correct `//+private` for `odin doc` --- src/checker.cpp | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/checker.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index ddb73d33e..44dc90c67 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -3446,6 +3446,13 @@ void check_collect_value_decl(CheckerContext *c, Ast *decl) { } } + if (entity_visibility_kind == EntityVisiblity_Public && + (c->scope->flags&ScopeFlag_File) && + c->scope->file && + (c->scope->file->flags & AstFile_IsPrivate)) { + entity_visibility_kind = EntityVisiblity_PrivateToPackage; + } + if (entity_visibility_kind != EntityVisiblity_Public && !(c->scope->flags&ScopeFlag_File)) { error(decl, "Attribute 'private' is not allowed on a non file scope entity"); } -- cgit v1.2.3 From ecdaac9921fbf351bfddaf920553855ae6a5d58f Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 19 Jan 2022 15:14:15 +0000 Subject: Unify `are_types_identical_unique_tuples` --- src/checker.cpp | 4 ++-- src/docs_writer.cpp | 2 +- src/exact_value.cpp | 2 +- src/types.cpp | 14 ++++++++++++-- 4 files changed, 16 insertions(+), 6 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index 44dc90c67..63a697072 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1253,7 +1253,7 @@ isize type_info_index(CheckerInfo *info, Type *type, bool error_on_failure) { // TODO(bill): This is O(n) and can be very slow for_array(i, info->type_info_map.entries){ auto *e = &info->type_info_map.entries[i]; - if (are_types_identical(e->key, type)) { + if (are_types_identical_unique_tuples(e->key, type)) { entry_index = e->value; // NOTE(bill): Add it to the search map map_set(&info->type_info_map, type, entry_index); @@ -1601,7 +1601,7 @@ void add_type_info_type_internal(CheckerContext *c, Type *t) { isize ti_index = -1; for_array(i, c->info->type_info_map.entries) { auto *e = &c->info->type_info_map.entries[i]; - if (are_types_identical(t, e->key)) { + if (are_types_identical_unique_tuples(t, e->key)) { // Duplicate entry ti_index = e->value; prev = true; diff --git a/src/docs_writer.cpp b/src/docs_writer.cpp index f1f110a57..c2d07dc12 100644 --- a/src/docs_writer.cpp +++ b/src/docs_writer.cpp @@ -483,7 +483,7 @@ OdinDocTypeIndex odin_doc_type(OdinDocWriter *w, Type *type) { for_array(i, w->type_cache.entries) { // NOTE(bill): THIS IS SLOW Type *other = w->type_cache.entries[i].key; - if (are_types_identical(type, other, true)) { + if (are_types_identical_unique_tuples(type, other)) { OdinDocTypeIndex index = w->type_cache.entries[i].value; map_set(&w->type_cache, type, index); return index; diff --git a/src/exact_value.cpp b/src/exact_value.cpp index e979e3d45..fd90278e5 100644 --- a/src/exact_value.cpp +++ b/src/exact_value.cpp @@ -9,7 +9,7 @@ struct Ast; struct HashKey; struct Type; struct Entity; -bool are_types_identical(Type *x, Type *y, bool check_tuple_names=false); +bool are_types_identical(Type *x, Type *y); struct Complex128 { f64 real, imag; diff --git a/src/types.cpp b/src/types.cpp index 98dc30703..07951196a 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -694,7 +694,7 @@ gbString type_to_string (Type *type); i64 type_size_of_internal(Type *t, TypePath *path); void init_map_internal_types(Type *type); Type * bit_set_to_int(Type *t); -bool are_types_identical(Type *x, Type *y, bool check_tuple_names/*=false*/); +bool are_types_identical(Type *x, Type *y); bool is_type_pointer(Type *t); bool is_type_proc(Type *t); @@ -2338,7 +2338,17 @@ Type *strip_type_aliasing(Type *x) { return x; } -bool are_types_identical(Type *x, Type *y, bool check_tuple_names) { +bool are_types_identical_internal(Type *x, Type *y, bool check_tuple_names); + +bool are_types_identical(Type *x, Type *y) { + return are_types_identical_internal(x, y, false); +} +bool are_types_identical_unique_tuples(Type *x, Type *y) { + return are_types_identical_internal(x, y, true); +} + + +bool are_types_identical_internal(Type *x, Type *y, bool check_tuple_names) { if (x == y) { return true; } -- cgit v1.2.3 From 3d7d3471924574beee08fc304a6daf6a8707d723 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 20 Jan 2022 19:56:05 +0000 Subject: Convert `ODIN_OS` and `ODIN_ARCH` to use enums rather than use strings --- core/c/c.odin | 8 ++--- core/c/libc/complex.odin | 4 +-- core/c/libc/ctype.odin | 4 +-- core/c/libc/errno.odin | 10 +++---- core/c/libc/math.odin | 4 +-- core/c/libc/setjmp.odin | 6 ++-- core/c/libc/signal.odin | 10 +++---- core/c/libc/stdio.odin | 10 +++---- core/c/libc/stdlib.odin | 10 +++---- core/c/libc/string.odin | 4 +-- core/c/libc/threads.odin | 6 ++-- core/c/libc/time.odin | 8 ++--- core/c/libc/uchar.odin | 4 +-- core/c/libc/wchar.odin | 4 +-- core/c/libc/wctype.odin | 10 +++---- core/crypto/_fiat/field_poly1305/field.odin | 2 +- core/crypto/chacha20/chacha20.odin | 2 +- core/crypto/rand_generic.odin | 2 +- core/image/png/example.odin | 2 +- core/image/png/helpers.odin | 2 +- core/os/file_windows.odin | 2 +- core/os/os.odin | 2 +- core/os/os2/user.odin | 16 +++++----- core/os/os_darwin.odin | 2 +- core/os/os_linux.odin | 26 ++++++++--------- core/os/stream.odin | 6 ++-- core/path/filepath/match.odin | 10 +++---- core/path/filepath/path.odin | 4 +-- core/path/filepath/path_unix.odin | 4 +-- core/runtime/core.odin | 2 +- core/runtime/default_allocators_nil.odin | 2 +- core/runtime/default_temporary_allocator.odin | 2 +- core/runtime/entry_windows.odin | 2 +- core/runtime/error_checks.odin | 4 +-- core/runtime/internal.odin | 2 +- core/runtime/procs.odin | 4 +-- core/sync/sync2/primitives.odin | 2 +- core/sync/sync2/primitives_internal.odin | 2 +- core/sys/unix/syscalls_linux.odin | 8 ++--- core/time/time_unix.odin | 2 +- src/checker.cpp | 37 ++++++++++++++++++++++-- vendor/ENet/enet.odin | 4 +-- vendor/OpenGL/helpers.odin | 2 +- vendor/botan/bindings/botan.odin | 6 ++-- vendor/glfw/bindings/bindings.odin | 6 ++-- vendor/glfw/native.odin | 6 ++-- vendor/miniaudio/common.odin | 6 ++-- vendor/miniaudio/data_conversion.odin | 4 +-- vendor/miniaudio/decoding.odin | 4 +-- vendor/miniaudio/device_io_procs.odin | 4 +-- vendor/miniaudio/device_io_types.odin | 32 ++++++++++---------- vendor/miniaudio/encoding.odin | 4 +-- vendor/miniaudio/filtering.odin | 4 +-- vendor/miniaudio/generation.odin | 4 +-- vendor/miniaudio/logging.odin | 4 +-- vendor/miniaudio/utilities.odin | 4 +-- vendor/miniaudio/vfs.odin | 4 +-- vendor/portmidi/portmidi.odin | 2 +- vendor/portmidi/util.odin | 2 +- vendor/raylib/raylib.odin | 6 ++-- vendor/raylib/rlgl.odin | 6 ++-- vendor/sdl2/image/sdl_image.odin | 8 ++--- vendor/sdl2/mixer/sdl_mixer.odin | 8 ++--- vendor/sdl2/net/sdl_net.odin | 8 ++--- vendor/sdl2/sdl2.odin | 8 ++--- vendor/sdl2/sdl_audio.odin | 8 ++--- vendor/sdl2/sdl_blendmode.odin | 8 ++--- vendor/sdl2/sdl_cpuinfo.odin | 8 ++--- vendor/sdl2/sdl_events.odin | 8 ++--- vendor/sdl2/sdl_gamecontroller.odin | 8 ++--- vendor/sdl2/sdl_gesture_haptic.odin | 8 ++--- vendor/sdl2/sdl_hints.odin | 8 ++--- vendor/sdl2/sdl_joystick.odin | 8 ++--- vendor/sdl2/sdl_keyboard.odin | 8 ++--- vendor/sdl2/sdl_log.odin | 8 ++--- vendor/sdl2/sdl_messagebox.odin | 8 ++--- vendor/sdl2/sdl_metal.odin | 8 ++--- vendor/sdl2/sdl_mouse.odin | 8 ++--- vendor/sdl2/sdl_mutex.odin | 8 ++--- vendor/sdl2/sdl_pixels.odin | 8 ++--- vendor/sdl2/sdl_rect.odin | 8 ++--- vendor/sdl2/sdl_render.odin | 8 ++--- vendor/sdl2/sdl_rwops.odin | 8 ++--- vendor/sdl2/sdl_stdinc.odin | 8 ++--- vendor/sdl2/sdl_surface.odin | 8 ++--- vendor/sdl2/sdl_system.odin | 8 ++--- vendor/sdl2/sdl_syswm.odin | 8 ++--- vendor/sdl2/sdl_thread.odin | 8 ++--- vendor/sdl2/sdl_timer.odin | 8 ++--- vendor/sdl2/sdl_touch.odin | 8 ++--- vendor/sdl2/sdl_video.odin | 8 ++--- vendor/sdl2/sdl_vulkan.odin | 8 ++--- vendor/sdl2/ttf/sdl_ttf.odin | 8 ++--- vendor/stb/image/stb_image.odin | 4 +-- vendor/stb/image/stb_image_resize.odin | 4 +-- vendor/stb/image/stb_image_write.odin | 4 +-- vendor/stb/rect_pack/stb_rect_pack.odin | 4 +-- vendor/stb/truetype/stb_truetype.odin | 4 +-- vendor/stb/vorbis/stb_vorbis.odin | 4 +-- vendor/vulkan/_gen/create_vulkan_odin_wrapper.py | 2 +- vendor/vulkan/structs.odin | 2 +- 101 files changed, 341 insertions(+), 310 deletions(-) (limited to 'src/checker.cpp') diff --git a/core/c/c.odin b/core/c/c.odin index d0b8e377f..05732476f 100644 --- a/core/c/c.odin +++ b/core/c/c.odin @@ -7,20 +7,20 @@ char :: builtin.u8 // assuming -funsigned-char schar :: builtin.i8 short :: builtin.i16 int :: builtin.i32 -long :: builtin.i32 when (ODIN_OS == "windows" || size_of(builtin.rawptr) == 4) else builtin.i64 +long :: builtin.i32 when (ODIN_OS == .Windows || size_of(builtin.rawptr) == 4) else builtin.i64 longlong :: builtin.i64 uchar :: builtin.u8 ushort :: builtin.u16 uint :: builtin.u32 -ulong :: builtin.u32 when (ODIN_OS == "windows" || size_of(builtin.rawptr) == 4) else builtin.u64 +ulong :: builtin.u32 when (ODIN_OS == .Windows || size_of(builtin.rawptr) == 4) else builtin.u64 ulonglong :: builtin.u64 bool :: builtin.bool size_t :: builtin.uint ssize_t :: builtin.int -wchar_t :: builtin.u16 when (ODIN_OS == "windows") else builtin.u32 +wchar_t :: builtin.u16 when (ODIN_OS == .Windows) else builtin.u32 float :: builtin.f32 double :: builtin.f64 @@ -48,7 +48,7 @@ int_least64_t :: builtin.i64 uint_least64_t :: builtin.u64 // Same on Windows, Linux, and FreeBSD -when ODIN_ARCH == "i386" || ODIN_ARCH == "amd64" { +when ODIN_ARCH == .i386 || ODIN_ARCH == .amd64 { int_fast8_t :: builtin.i8 uint_fast8_t :: builtin.u8 int_fast16_t :: builtin.i32 diff --git a/core/c/libc/complex.odin b/core/c/libc/complex.odin index 62b28f0cd..22c422cce 100644 --- a/core/c/libc/complex.odin +++ b/core/c/libc/complex.odin @@ -2,9 +2,9 @@ package libc // 7.3 Complex arithmetic -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { foreign import libc "system:libucrt.lib" -} else when ODIN_OS == "darwin" { +} else when ODIN_OS == .Darwin { foreign import libc "system:System.framework" } else { foreign import libc "system:c" diff --git a/core/c/libc/ctype.odin b/core/c/libc/ctype.odin index 05d9dcd37..185385a5e 100644 --- a/core/c/libc/ctype.odin +++ b/core/c/libc/ctype.odin @@ -1,8 +1,8 @@ package libc -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { foreign import libc "system:libucrt.lib" -} else when ODIN_OS == "darwin" { +} else when ODIN_OS == .Darwin { foreign import libc "system:System.framework" } else { foreign import libc "system:c" diff --git a/core/c/libc/errno.odin b/core/c/libc/errno.odin index 8ebe2f734..ecde6af59 100644 --- a/core/c/libc/errno.odin +++ b/core/c/libc/errno.odin @@ -2,9 +2,9 @@ package libc // 7.5 Errors -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { foreign import libc "system:libucrt.lib" -} else when ODIN_OS == "darwin" { +} else when ODIN_OS == .Darwin { foreign import libc "system:System.framework" } else { foreign import libc "system:c" @@ -14,7 +14,7 @@ when ODIN_OS == "windows" { // EDOM, // EILSEQ // ERANGE -when ODIN_OS == "linux" || ODIN_OS == "freebsd" { +when ODIN_OS == .Linux || ODIN_OS == .FreeBSD { @(private="file") @(default_calling_convention="c") foreign libc { @@ -27,7 +27,7 @@ when ODIN_OS == "linux" || ODIN_OS == "freebsd" { ERANGE :: 34 } -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { @(private="file") @(default_calling_convention="c") foreign libc { @@ -40,7 +40,7 @@ when ODIN_OS == "windows" { ERANGE :: 34 } -when ODIN_OS == "darwin" { +when ODIN_OS == .Darwin { @(private="file") @(default_calling_convention="c") foreign libc { diff --git a/core/c/libc/math.odin b/core/c/libc/math.odin index ee702b82e..97f77236f 100644 --- a/core/c/libc/math.odin +++ b/core/c/libc/math.odin @@ -4,9 +4,9 @@ package libc import "core:intrinsics" -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { foreign import libc "system:libucrt.lib" -} else when ODIN_OS == "darwin" { +} else when ODIN_OS == .Darwin { foreign import libc "system:System.framework" } else { foreign import libc "system:c" diff --git a/core/c/libc/setjmp.odin b/core/c/libc/setjmp.odin index dcd4a9c64..c2cd1d047 100644 --- a/core/c/libc/setjmp.odin +++ b/core/c/libc/setjmp.odin @@ -2,14 +2,14 @@ package libc // 7.13 Nonlocal jumps -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { foreign import libc "system:libucrt.lib" -} else when ODIN_OS == "darwin" { +} else when ODIN_OS == .Darwin { foreign import libc "system:System.framework" } else { foreign import libc "system:c" } -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { @(default_calling_convention="c") foreign libc { // 7.13.1 Save calling environment diff --git a/core/c/libc/signal.odin b/core/c/libc/signal.odin index e1044dc02..186b74d8c 100644 --- a/core/c/libc/signal.odin +++ b/core/c/libc/signal.odin @@ -2,9 +2,9 @@ package libc // 7.14 Signal handling -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { foreign import libc "system:libucrt.lib" -} else when ODIN_OS == "darwin" { +} else when ODIN_OS == .Darwin { foreign import libc "system:System.framework" } else { foreign import libc "system:c" @@ -21,7 +21,7 @@ foreign libc { raise :: proc(sig: int) -> int --- } -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { SIG_ERR :: rawptr(~uintptr(0)) SIG_DFL :: rawptr(uintptr(0)) SIG_IGN :: rawptr(uintptr(1)) @@ -34,7 +34,7 @@ when ODIN_OS == "windows" { SIGTERM :: 15 } -when ODIN_OS == "linux" || ODIN_OS == "freebsd" { +when ODIN_OS == .Linux || ODIN_OS == .FreeBSD { SIG_ERR :: rawptr(~uintptr(0)) SIG_DFL :: rawptr(uintptr(0)) SIG_IGN :: rawptr(uintptr(1)) @@ -47,7 +47,7 @@ when ODIN_OS == "linux" || ODIN_OS == "freebsd" { SIGTERM :: 15 } -when ODIN_OS == "darwin" { +when ODIN_OS == .Darwin { SIG_ERR :: rawptr(~uintptr(0)) SIG_DFL :: rawptr(uintptr(0)) SIG_IGN :: rawptr(uintptr(1)) diff --git a/core/c/libc/stdio.odin b/core/c/libc/stdio.odin index 4a39c22e9..33be34625 100644 --- a/core/c/libc/stdio.odin +++ b/core/c/libc/stdio.odin @@ -1,8 +1,8 @@ package libc -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { foreign import libc "system:libucrt.lib" -} else when ODIN_OS == "darwin" { +} else when ODIN_OS == .Darwin { foreign import libc "system:System.framework" } else { foreign import libc "system:c" @@ -13,7 +13,7 @@ when ODIN_OS == "windows" { FILE :: struct {} // MSVCRT compatible. -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { _IOFBF :: 0x0000 _IONBF :: 0x0004 _IOLBF :: 0x0040 @@ -48,7 +48,7 @@ when ODIN_OS == "windows" { } // GLIBC and MUSL compatible. -when ODIN_OS == "linux" { +when ODIN_OS == .Linux { fpos_t :: struct #raw_union { _: [16]char, _: longlong, _: double, } _IOFBF :: 0 @@ -78,7 +78,7 @@ when ODIN_OS == "linux" { } } -when ODIN_OS == "darwin" { +when ODIN_OS == .Darwin { fpos_t :: distinct i64 _IOFBF :: 0 diff --git a/core/c/libc/stdlib.odin b/core/c/libc/stdlib.odin index b368c0cee..a278db0ef 100644 --- a/core/c/libc/stdlib.odin +++ b/core/c/libc/stdlib.odin @@ -2,15 +2,15 @@ package libc // 7.22 General utilities -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { foreign import libc "system:libucrt.lib" -} else when ODIN_OS == "darwin" { +} else when ODIN_OS == .Darwin { foreign import libc "system:System.framework" } else { foreign import libc "system:c" } -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { RAND_MAX :: 0x7fff @(private="file") @@ -24,7 +24,7 @@ when ODIN_OS == "windows" { } } -when ODIN_OS == "linux" { +when ODIN_OS == .Linux { RAND_MAX :: 0x7fffffff // GLIBC and MUSL only @@ -40,7 +40,7 @@ when ODIN_OS == "linux" { } -when ODIN_OS == "darwin" { +when ODIN_OS == .Darwin { RAND_MAX :: 0x7fffffff // GLIBC and MUSL only diff --git a/core/c/libc/string.odin b/core/c/libc/string.odin index c91124dcb..8f83ee1b9 100644 --- a/core/c/libc/string.odin +++ b/core/c/libc/string.odin @@ -4,9 +4,9 @@ import "core:runtime" // 7.24 String handling -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { foreign import libc "system:libucrt.lib" -} else when ODIN_OS == "darwin" { +} else when ODIN_OS == .Darwin { foreign import libc "system:System.framework" } else { foreign import libc "system:c" diff --git a/core/c/libc/threads.odin b/core/c/libc/threads.odin index ad305b517..a7a45150d 100644 --- a/core/c/libc/threads.odin +++ b/core/c/libc/threads.odin @@ -5,7 +5,7 @@ package libc thrd_start_t :: proc "c" (rawptr) -> int tss_dtor_t :: proc "c" (rawptr) -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { foreign import libc { "system:libucrt.lib", "system:msvcprt.lib" @@ -74,7 +74,7 @@ when ODIN_OS == "windows" { } // GLIBC and MUSL compatible constants and types. -when ODIN_OS == "linux" { +when ODIN_OS == .Linux { foreign import libc { "system:c", "system:pthread" @@ -138,6 +138,6 @@ when ODIN_OS == "linux" { } -when ODIN_OS == "darwin" { +when ODIN_OS == .Darwin { // TODO: find out what this is meant to be! } diff --git a/core/c/libc/time.odin b/core/c/libc/time.odin index 96e80e216..b3539a227 100644 --- a/core/c/libc/time.odin +++ b/core/c/libc/time.odin @@ -2,9 +2,9 @@ package libc // 7.27 Date and time -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { foreign import libc "system:libucrt.lib" -} else when ODIN_OS == "darwin" { +} else when ODIN_OS == .Darwin { foreign import libc "system:System.framework" } else { foreign import libc "system:c" @@ -12,7 +12,7 @@ when ODIN_OS == "windows" { // We enforce 64-bit time_t and timespec as there is no reason to use 32-bit as // we approach the 2038 problem. Windows has defaulted to this since VC8 (2005). -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { foreign libc { // 7.27.2 Time manipulation functions clock :: proc() -> clock_t --- @@ -45,7 +45,7 @@ when ODIN_OS == "windows" { } } -when ODIN_OS == "linux" || ODIN_OS == "freebsd" || ODIN_OS == "darwin" { +when ODIN_OS == .Linux || ODIN_OS == .FreeBSD || ODIN_OS == .Darwin { @(default_calling_convention="c") foreign libc { // 7.27.2 Time manipulation functions diff --git a/core/c/libc/uchar.odin b/core/c/libc/uchar.odin index e49c29e51..a10969ceb 100644 --- a/core/c/libc/uchar.odin +++ b/core/c/libc/uchar.odin @@ -2,9 +2,9 @@ package libc // 7.28 Unicode utilities -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { foreign import libc "system:libucrt.lib" -} else when ODIN_OS == "darwin" { +} else when ODIN_OS == .Darwin { foreign import libc "system:System.framework" } else { foreign import libc "system:c" diff --git a/core/c/libc/wchar.odin b/core/c/libc/wchar.odin index fc206e494..f2aa8410e 100644 --- a/core/c/libc/wchar.odin +++ b/core/c/libc/wchar.odin @@ -2,9 +2,9 @@ package libc // 7.29 Extended multibyte and wide character utilities -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { foreign import libc "system:libucrt.lib" -} else when ODIN_OS == "darwin" { +} else when ODIN_OS == .Darwin { foreign import libc "system:System.framework" } else { foreign import libc "system:c" diff --git a/core/c/libc/wctype.odin b/core/c/libc/wctype.odin index 47f17e0b4..942726ba6 100644 --- a/core/c/libc/wctype.odin +++ b/core/c/libc/wctype.odin @@ -2,25 +2,25 @@ package libc // 7.30 Wide character classification and mapping utilities -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { foreign import libc "system:libucrt.lib" -} else when ODIN_OS == "darwin" { +} else when ODIN_OS == .Darwin { foreign import libc "system:System.framework" } else { foreign import libc "system:c" } -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { wctrans_t :: distinct wchar_t wctype_t :: distinct ushort } -when ODIN_OS == "linux" { +when ODIN_OS == .Linux { wctrans_t :: distinct intptr_t wctype_t :: distinct ulong } -when ODIN_OS == "darwin" { +when ODIN_OS == .Darwin { wctrans_t :: distinct int wctype_t :: distinct u32 } diff --git a/core/crypto/_fiat/field_poly1305/field.odin b/core/crypto/_fiat/field_poly1305/field.odin index 4ed8acbff..ca458e079 100644 --- a/core/crypto/_fiat/field_poly1305/field.odin +++ b/core/crypto/_fiat/field_poly1305/field.odin @@ -22,7 +22,7 @@ fe_from_bytes :: #force_inline proc (out1: ^Tight_Field_Element, arg1: []byte, a assert(len(arg1) == 16) - when ODIN_ARCH == "i386" || ODIN_ARCH == "amd64" { + when ODIN_ARCH == .i386 || ODIN_ARCH == .amd64 { // While it may be unwise to do deserialization here on our // own when fiat-crypto provides equivalent functionality, // doing it this way provides a little under 3x performance diff --git a/core/crypto/chacha20/chacha20.odin b/core/crypto/chacha20/chacha20.odin index e32dacb2c..229949c22 100644 --- a/core/crypto/chacha20/chacha20.odin +++ b/core/crypto/chacha20/chacha20.odin @@ -346,7 +346,7 @@ _do_blocks :: proc (ctx: ^Context, dst, src: []byte, nr_blocks: int) { // Until dedicated assembly can be written leverage the fact that // the callers of this routine ensure that src/dst are valid. - when ODIN_ARCH == "i386" || ODIN_ARCH == "amd64" { + when ODIN_ARCH == .i386 || ODIN_ARCH == .amd64 { // util.PUT_U32_LE/util.U32_LE are not required on little-endian // systems that also happen to not be strict about aligned // memory access. diff --git a/core/crypto/rand_generic.odin b/core/crypto/rand_generic.odin index 98890b5b1..be6987ee2 100644 --- a/core/crypto/rand_generic.odin +++ b/core/crypto/rand_generic.odin @@ -1,6 +1,6 @@ package crypto -when ODIN_OS != "linux" { +when ODIN_OS != .Linux { _rand_bytes :: proc (dst: []byte) { unimplemented("crypto: rand_bytes not supported on this OS") } diff --git a/core/image/png/example.odin b/core/image/png/example.odin index f4eb5128e..17436c260 100644 --- a/core/image/png/example.odin +++ b/core/image/png/example.odin @@ -207,7 +207,7 @@ write_image_as_ppm :: proc(filename: string, image: ^image.Image) -> (success: b } mode: int = 0 - when ODIN_OS == "linux" || ODIN_OS == "darwin" { + when ODIN_OS == .Linux || ODIN_OS == .Darwin { // NOTE(justasd): 644 (owner read, write; group read; others read) mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH } diff --git a/core/image/png/helpers.odin b/core/image/png/helpers.odin index ecc0183bc..6ec674544 100644 --- a/core/image/png/helpers.odin +++ b/core/image/png/helpers.odin @@ -443,7 +443,7 @@ when false { } mode: int = 0 - when ODIN_OS == "linux" || ODIN_OS == "darwin" { + when ODIN_OS == .Linux || ODIN_OS == .Darwin { // NOTE(justasd): 644 (owner read, write; group read; others read) mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH } diff --git a/core/os/file_windows.odin b/core/os/file_windows.odin index 419f8bbc2..8a0f2ed64 100644 --- a/core/os/file_windows.odin +++ b/core/os/file_windows.odin @@ -399,7 +399,7 @@ is_abs :: proc(path: string) -> bool { if len(path) > 0 && path[0] == '/' { return true } - when ODIN_OS == "windows" { + when ODIN_OS == .Windows { if len(path) > 2 { switch path[0] { case 'A'..='Z', 'a'..='z': diff --git a/core/os/os.odin b/core/os/os.odin index 83158be80..19a8099ef 100644 --- a/core/os/os.odin +++ b/core/os/os.odin @@ -139,7 +139,7 @@ write_entire_file :: proc(name: string, data: []byte, truncate := true) -> (succ } mode: int = 0 - when OS == "linux" || OS == "darwin" { + when OS == .Linux || OS == .Darwin { // NOTE(justasd): 644 (owner read, write; group read; others read) mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH } diff --git a/core/os/os2/user.odin b/core/os/os2/user.odin index 6dd99c621..976e61bb1 100644 --- a/core/os/os2/user.odin +++ b/core/os/os2/user.odin @@ -3,13 +3,13 @@ package os2 import "core:strings" user_cache_dir :: proc(allocator := context.allocator) -> (dir: string, is_defined: bool) { - switch ODIN_OS { - case "windows": + #partial switch ODIN_OS { + case .Windows: dir = get_env("LocalAppData") if dir != "" { dir = strings.clone(dir, allocator) } - case "darwin": + case .Darwin: dir = get_env("HOME") if dir != "" { dir = strings.concatenate({dir, "/Library/Caches"}, allocator) @@ -29,13 +29,13 @@ user_cache_dir :: proc(allocator := context.allocator) -> (dir: string, is_defin } user_config_dir :: proc(allocator := context.allocator) -> (dir: string, is_defined: bool) { - switch ODIN_OS { - case "windows": + #partial switch ODIN_OS { + case .Windows: dir = get_env("AppData") if dir != "" { dir = strings.clone(dir, allocator) } - case "darwin": + case .Darwin: dir = get_env("HOME") if dir != "" { dir = strings.concatenate({dir, "/Library/Application Support"}, allocator) @@ -56,8 +56,8 @@ user_config_dir :: proc(allocator := context.allocator) -> (dir: string, is_defi user_home_dir :: proc() -> (dir: string, is_defined: bool) { env := "HOME" - switch ODIN_OS { - case "windows": + #partial switch ODIN_OS { + case .Windows: env = "USERPROFILE" } if v := get_env(env); v != "" { diff --git a/core/os/os_darwin.odin b/core/os/os_darwin.odin index b32453a5d..4828c5167 100644 --- a/core/os/os_darwin.odin +++ b/core/os/os_darwin.odin @@ -335,7 +335,7 @@ open :: proc(path: string, flags: int = O_RDWR, mode: int = 0) -> (Handle, Errno return INVALID_HANDLE, 1 } -when ODIN_OS == "darwin" && ODIN_ARCH == "arm64" { +when ODIN_OS == .Darwin && ODIN_ARCH == .arm64 { if mode != 0 { err := fchmod(handle, cast(u16)mode) if err != 0 { diff --git a/core/os/os_linux.odin b/core/os/os_linux.odin index 1c796f1b8..3eb76249c 100644 --- a/core/os/os_linux.odin +++ b/core/os/os_linux.odin @@ -271,7 +271,7 @@ AT_REMOVEDIR :: uintptr(0x200) AT_SYMLINK_NOFOLLOW :: uintptr(0x100) _unix_open :: proc(path: cstring, flags: int, mode: int = 0o000) -> Handle { - when ODIN_ARCH != "arm64" { + when ODIN_ARCH != .arm64 { res := int(intrinsics.syscall(unix.SYS_open, uintptr(rawptr(path)), uintptr(flags), uintptr(mode))) } else { // NOTE: arm64 does not have open res := int(intrinsics.syscall(unix.SYS_openat, uintptr(AT_FDCWD), uintptr(rawptr(path), uintptr(flags), uintptr(mode)))) @@ -292,7 +292,7 @@ _unix_write :: proc(fd: Handle, buf: rawptr, size: uint) -> int { } _unix_seek :: proc(fd: Handle, offset: i64, whence: int) -> i64 { - when ODIN_ARCH == "amd64" || ODIN_ARCH == "arm64" { + when ODIN_ARCH == .amd64 || ODIN_ARCH == .arm64 { return i64(intrinsics.syscall(unix.SYS_lseek, uintptr(fd), uintptr(offset), uintptr(whence))) } else { low := uintptr(offset & 0xFFFFFFFF) @@ -304,9 +304,9 @@ _unix_seek :: proc(fd: Handle, offset: i64, whence: int) -> i64 { } _unix_stat :: proc(path: cstring, stat: ^OS_Stat) -> int { - when ODIN_ARCH == "amd64" { + when ODIN_ARCH == .amd64 { return int(intrinsics.syscall(unix.SYS_stat, uintptr(rawptr(path)), uintptr(stat))) - } else when ODIN_ARCH != "arm64" { + } else when ODIN_ARCH != .arm64 { return int(intrinsics.syscall(unix.SYS_stat64, uintptr(rawptr(path)), uintptr(stat))) } else { // NOTE: arm64 does not have stat return int(intrinsics.syscall(unix.SYS_fstatat, uintptr(AT_FDCWD), uintptr(rawptr(path)), uintptr(stat), 0)) @@ -314,7 +314,7 @@ _unix_stat :: proc(path: cstring, stat: ^OS_Stat) -> int { } _unix_fstat :: proc(fd: Handle, stat: ^OS_Stat) -> int { - when ODIN_ARCH == "amd64" || ODIN_ARCH == "arm64" { + when ODIN_ARCH == .amd64 || ODIN_ARCH == .arm64 { return int(intrinsics.syscall(unix.SYS_fstat, uintptr(fd), uintptr(stat))) } else { return int(intrinsics.syscall(unix.SYS_fstat64, uintptr(fd), uintptr(stat))) @@ -322,9 +322,9 @@ _unix_fstat :: proc(fd: Handle, stat: ^OS_Stat) -> int { } _unix_lstat :: proc(path: cstring, stat: ^OS_Stat) -> int { - when ODIN_ARCH == "amd64" { + when ODIN_ARCH == .amd64 { return int(intrinsics.syscall(unix.SYS_lstat, uintptr(rawptr(path)), uintptr(stat))) - } else when ODIN_ARCH != "arm64" { + } else when ODIN_ARCH != .arm64 { return int(intrinsics.syscall(unix.SYS_lstat64, uintptr(rawptr(path)), uintptr(stat))) } else { // NOTE: arm64 does not have any lstat return int(intrinsics.syscall(unix.SYS_fstatat, uintptr(AT_FDCWD), uintptr(rawptr(path)), uintptr(stat), AT_SYMLINK_NOFOLLOW)) @@ -332,7 +332,7 @@ _unix_lstat :: proc(path: cstring, stat: ^OS_Stat) -> int { } _unix_readlink :: proc(path: cstring, buf: rawptr, bufsiz: uint) -> int { - when ODIN_ARCH != "arm64" { + when ODIN_ARCH != .arm64 { return int(intrinsics.syscall(unix.SYS_readlink, uintptr(rawptr(path)), uintptr(buf), uintptr(bufsiz))) } else { // NOTE: arm64 does not have readlink return int(intrinsics.syscall(unix.SYS_readlinkat, uintptr(AT_FDCWD), uintptr(rawptr(path)), uintptr(buf), uintptr(bufsiz))) @@ -340,7 +340,7 @@ _unix_readlink :: proc(path: cstring, buf: rawptr, bufsiz: uint) -> int { } _unix_access :: proc(path: cstring, mask: int) -> int { - when ODIN_ARCH != "arm64" { + when ODIN_ARCH != .arm64 { return int(intrinsics.syscall(unix.SYS_access, uintptr(rawptr(path)), uintptr(mask))) } else { // NOTE: arm64 does not have access return int(intrinsics.syscall(unix.SYS_faccessat, uintptr(AT_FDCWD), uintptr(rawptr(path)), uintptr(mask))) @@ -356,7 +356,7 @@ _unix_chdir :: proc(path: cstring) -> int { } _unix_rename :: proc(old, new: cstring) -> int { - when ODIN_ARCH != "arm64" { + when ODIN_ARCH != .arm64 { return int(intrinsics.syscall(unix.SYS_rename, uintptr(rawptr(old)), uintptr(rawptr(new)))) } else { // NOTE: arm64 does not have rename return int(intrinsics.syscall(unix.SYS_renameat, uintptr(AT_FDCWD), uintptr(rawptr(old)), uintptr(rawptr(new)))) @@ -364,7 +364,7 @@ _unix_rename :: proc(old, new: cstring) -> int { } _unix_unlink :: proc(path: cstring) -> int { - when ODIN_ARCH != "arm64" { + when ODIN_ARCH != .arm64 { return int(intrinsics.syscall(unix.SYS_unlink, uintptr(rawptr(path)))) } else { // NOTE: arm64 does not have unlink return int(intrinsics.syscall(unix.SYS_unlinkat, uintptr(AT_FDCWD), uintptr(rawptr(path), 0))) @@ -372,7 +372,7 @@ _unix_unlink :: proc(path: cstring) -> int { } _unix_rmdir :: proc(path: cstring) -> int { - when ODIN_ARCH != "arm64" { + when ODIN_ARCH != .arm64 { return int(intrinsics.syscall(unix.SYS_rmdir, uintptr(rawptr(path)))) } else { // NOTE: arm64 does not have rmdir return int(intrinsics.syscall(unix.SYS_unlinkat, uintptr(AT_FDCWD), uintptr(rawptr(path)), AT_REMOVEDIR)) @@ -380,7 +380,7 @@ _unix_rmdir :: proc(path: cstring) -> int { } _unix_mkdir :: proc(path: cstring, mode: u32) -> int { - when ODIN_ARCH != "arm64" { + when ODIN_ARCH != .arm64 { return int(intrinsics.syscall(unix.SYS_mkdir, uintptr(rawptr(path)), uintptr(mode))) } else { // NOTE: arm64 does not have mkdir return int(intrinsics.syscall(unix.SYS_mkdirat, uintptr(AT_FDCWD), uintptr(rawptr(path)), uintptr(mode))) diff --git a/core/os/stream.odin b/core/os/stream.odin index 5cf5c8405..2c6e1d47f 100644 --- a/core/os/stream.odin +++ b/core/os/stream.odin @@ -19,7 +19,7 @@ _file_stream_vtable := &io.Stream_VTable{ return }, impl_read_at = proc(s: io.Stream, p: []byte, offset: i64) -> (n: int, err: io.Error) { - when ODIN_OS == "windows" || ODIN_OS == "wasi" { + when ODIN_OS == .Windows || ODIN_OS == .WASI { fd := Handle(uintptr(s.stream_data)) os_err: Errno n, os_err = read_at(fd, p, offset) @@ -33,7 +33,7 @@ _file_stream_vtable := &io.Stream_VTable{ return }, impl_write_at = proc(s: io.Stream, p: []byte, offset: i64) -> (n: int, err: io.Error) { - when ODIN_OS == "windows" || ODIN_OS == "wasi" { + when ODIN_OS == .Windows || ODIN_OS == .WASI { fd := Handle(uintptr(s.stream_data)) os_err: Errno n, os_err = write_at(fd, p, offset) @@ -53,7 +53,7 @@ _file_stream_vtable := &io.Stream_VTable{ return sz }, impl_flush = proc(s: io.Stream) -> io.Error { - when ODIN_OS == "windows" { + when ODIN_OS == .Windows { fd := Handle(uintptr(s.stream_data)) flush(fd) } else { diff --git a/core/path/filepath/match.odin b/core/path/filepath/match.odin index cba44953d..c045f3ece 100644 --- a/core/path/filepath/match.odin +++ b/core/path/filepath/match.odin @@ -89,7 +89,7 @@ scan_chunk :: proc(pattern: string) -> (star: bool, chunk, rest: string) { scan_loop: for i = 0; i < len(pattern); i += 1 { switch pattern[i] { case '\\': - when ODIN_OS != "windows" { + when ODIN_OS != .Windows { if i+1 < len(pattern) { i += 1 } @@ -161,7 +161,7 @@ match_chunk :: proc(chunk, s: string) -> (rest: string, ok: bool, err: Match_Err chunk = chunk[1:] case '\\': - when ODIN_OS != "windows" { + when ODIN_OS != .Windows { chunk = chunk[1:] if len(chunk) == 0 { err = .Syntax_Error @@ -188,7 +188,7 @@ get_escape :: proc(chunk: string) -> (r: rune, next_chunk: string, err: Match_Er return } chunk := chunk - if chunk[0] == '\\' && ODIN_OS != "windows" { + if chunk[0] == '\\' && ODIN_OS != .Windows { chunk = chunk[1:] if len(chunk) == 0 { err = .Syntax_Error @@ -231,7 +231,7 @@ glob :: proc(pattern: string, allocator := context.allocator) -> (matches: []str dir, file := split(pattern) volume_len := 0 - when ODIN_OS == "windows" { + when ODIN_OS == .Windows { volume_len, dir = clean_glob_path_windows(dir, temp_buf[:]) } else { dir = clean_glob_path(dir) @@ -308,7 +308,7 @@ _glob :: proc(dir, pattern: string, matches: ^[dynamic]string) -> (m: [dynamic]s @(private) has_meta :: proc(path: string) -> bool { - when ODIN_OS == "windows" { + when ODIN_OS == .Windows { CHARS :: `*?[` } else { CHARS :: `*?[\` diff --git a/core/path/filepath/path.odin b/core/path/filepath/path.odin index 39cd80a47..d6e36f649 100644 --- a/core/path/filepath/path.odin +++ b/core/path/filepath/path.odin @@ -8,7 +8,7 @@ import "core:strings" is_separator :: proc(c: byte) -> bool { switch c { case '/': return true - case '\\': return ODIN_OS == "windows" + case '\\': return ODIN_OS == .Windows } return false } @@ -32,7 +32,7 @@ volume_name :: proc(path: string) -> string { } volume_name_len :: proc(path: string) -> int { - if ODIN_OS == "windows" { + if ODIN_OS == .Windows { if len(path) < 2 { return 0 } diff --git a/core/path/filepath/path_unix.odin b/core/path/filepath/path_unix.odin index 1db528a2f..3e49c4710 100644 --- a/core/path/filepath/path_unix.odin +++ b/core/path/filepath/path_unix.odin @@ -1,7 +1,7 @@ //+build linux, darwin, freebsd package filepath -when ODIN_OS == "darwin" { +when ODIN_OS == .Darwin { foreign import libc "System.framework" } else { foreign import libc "system:c" @@ -54,7 +54,7 @@ foreign libc { @(link_name="free") _unix_free :: proc(ptr: rawptr) --- } -when ODIN_OS == "darwin" { +when ODIN_OS == .Darwin { @(private) foreign libc { @(link_name="__error") __error :: proc() -> ^i32 --- diff --git a/core/runtime/core.odin b/core/runtime/core.odin index 424650828..cd76b0bb5 100644 --- a/core/runtime/core.odin +++ b/core/runtime/core.odin @@ -539,7 +539,7 @@ __init_context :: proc "contextless" (c: ^Context) { } default_assertion_failure_proc :: proc(prefix, message: string, loc: Source_Code_Location) -> ! { - when ODIN_OS == "freestanding" { + when ODIN_OS == .Freestanding { // Do nothing } else { print_caller_location(loc) diff --git a/core/runtime/default_allocators_nil.odin b/core/runtime/default_allocators_nil.odin index ccb4a3381..04dea0e19 100644 --- a/core/runtime/default_allocators_nil.odin +++ b/core/runtime/default_allocators_nil.odin @@ -32,7 +32,7 @@ nil_allocator :: proc() -> Allocator { -when ODIN_OS == "freestanding" { +when ODIN_OS == .Freestanding { default_allocator_proc :: nil_allocator_proc default_allocator :: nil_allocator } \ No newline at end of file diff --git a/core/runtime/default_temporary_allocator.odin b/core/runtime/default_temporary_allocator.odin index 01143e222..4337e555b 100644 --- a/core/runtime/default_temporary_allocator.odin +++ b/core/runtime/default_temporary_allocator.odin @@ -3,7 +3,7 @@ package runtime DEFAULT_TEMP_ALLOCATOR_BACKING_SIZE: int : #config(DEFAULT_TEMP_ALLOCATOR_BACKING_SIZE, 1<<22) -when ODIN_OS == "freestanding" || ODIN_OS == "js" || ODIN_DEFAULT_TO_NIL_ALLOCATOR { +when ODIN_OS == .Freestanding || ODIN_OS == .JS || ODIN_DEFAULT_TO_NIL_ALLOCATOR { Default_Temp_Allocator :: struct {} default_temp_allocator_init :: proc(s: ^Default_Temp_Allocator, size: int, backup_allocator := context.allocator) {} diff --git a/core/runtime/entry_windows.odin b/core/runtime/entry_windows.odin index 35a6bb421..2f323cb41 100644 --- a/core/runtime/entry_windows.odin +++ b/core/runtime/entry_windows.odin @@ -22,7 +22,7 @@ when ODIN_BUILD_MODE == .Dynamic { return true } } else when !ODIN_TEST && !ODIN_NO_ENTRY_POINT { - when ODIN_ARCH == "i386" || ODIN_NO_CRT { + when ODIN_ARCH == .i386 || ODIN_NO_CRT { @(link_name="mainCRTStartup", linkage="strong", require) mainCRTStartup :: proc "stdcall" () -> i32 { context = default_context() diff --git a/core/runtime/error_checks.odin b/core/runtime/error_checks.odin index 7f1aeb2d7..ed75cbea6 100644 --- a/core/runtime/error_checks.odin +++ b/core/runtime/error_checks.odin @@ -1,7 +1,7 @@ package runtime bounds_trap :: proc "contextless" () -> ! { - when ODIN_OS == "windows" { + when ODIN_OS == .Windows { windows_trap_array_bounds() } else { trap() @@ -9,7 +9,7 @@ bounds_trap :: proc "contextless" () -> ! { } type_assertion_trap :: proc "contextless" () -> ! { - when ODIN_OS == "windows" { + when ODIN_OS == .Windows { windows_trap_type_assertion() } else { trap() diff --git a/core/runtime/internal.odin b/core/runtime/internal.odin index 7b283a132..0d0e196c4 100644 --- a/core/runtime/internal.odin +++ b/core/runtime/internal.odin @@ -3,7 +3,7 @@ package runtime import "core:intrinsics" @(private="file") -IS_WASM :: ODIN_ARCH == "wasm32" || ODIN_ARCH == "wasm64" +IS_WASM :: ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64 @(private) RUNTIME_LINKAGE :: "strong" when ( diff --git a/core/runtime/procs.odin b/core/runtime/procs.odin index 961f6376f..5a1d11fe0 100644 --- a/core/runtime/procs.odin +++ b/core/runtime/procs.odin @@ -1,6 +1,6 @@ package runtime -when ODIN_NO_CRT && ODIN_OS == "windows" { +when ODIN_NO_CRT && ODIN_OS == .Windows { foreign import lib "system:NtDll.lib" @(private="file") @@ -25,7 +25,7 @@ when ODIN_NO_CRT && ODIN_OS == "windows" { RtlMoveMemory(dst, src, len) return dst } -} else when ODIN_NO_CRT || (ODIN_ARCH == "wasm32" || ODIN_ARCH == "wasm64") { +} else when ODIN_NO_CRT || (ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64) { @(link_name="memset", linkage="strong", require) memset :: proc "c" (ptr: rawptr, val: i32, len: int) -> rawptr { if ptr != nil && len != 0 { diff --git a/core/sync/sync2/primitives.odin b/core/sync/sync2/primitives.odin index 6d056d439..046ecbc35 100644 --- a/core/sync/sync2/primitives.odin +++ b/core/sync/sync2/primitives.odin @@ -11,7 +11,7 @@ current_thread_id :: proc "contextless" () -> int { // // A Mutex must not be copied after first use Mutex :: struct { - impl: _Mutex, + impl: _Mutex `This is a tag`, } // mutex_lock locks m diff --git a/core/sync/sync2/primitives_internal.odin b/core/sync/sync2/primitives_internal.odin index ae7e2599c..eb692c6ae 100644 --- a/core/sync/sync2/primitives_internal.odin +++ b/core/sync/sync2/primitives_internal.odin @@ -93,7 +93,7 @@ when #config(ODIN_SYNC_RECURSIVE_MUTEX_USE_FUTEX, true) { } -when ODIN_OS != "windows" { +when ODIN_OS != .Windows { RW_Mutex_State :: distinct uint RW_Mutex_State_Half_Width :: size_of(RW_Mutex_State)*8/2 RW_Mutex_State_Is_Writing :: RW_Mutex_State(1) diff --git a/core/sys/unix/syscalls_linux.odin b/core/sys/unix/syscalls_linux.odin index 3dc3d2c74..0082c7261 100644 --- a/core/sys/unix/syscalls_linux.odin +++ b/core/sys/unix/syscalls_linux.odin @@ -15,7 +15,7 @@ import "core:intrinsics" // 386: arch/x86/entry/syscalls/sycall_32.tbl // arm: arch/arm/tools/syscall.tbl -when ODIN_ARCH == "amd64" { +when ODIN_ARCH == .amd64 { SYS_read : uintptr : 0 SYS_write : uintptr : 1 SYS_open : uintptr : 2 @@ -374,7 +374,7 @@ when ODIN_ARCH == "amd64" { SYS_landlock_add_rule : uintptr : 445 SYS_landlock_restrict_self : uintptr : 446 SYS_memfd_secret : uintptr : 447 -} else when ODIN_ARCH == "arm64" { +} else when ODIN_ARCH == .arm64 { SYS_io_setup : uintptr : 0 SYS_io_destroy : uintptr : 1 SYS_io_submit : uintptr : 2 @@ -675,7 +675,7 @@ when ODIN_ARCH == "amd64" { SYS_landlock_create_ruleset : uintptr : 444 SYS_landlock_add_rule : uintptr : 445 SYS_landlock_restrict_self : uintptr : 446 -} else when ODIN_ARCH == "i386" { +} else when ODIN_ARCH == .i386 { SYS_restart_syscall : uintptr : 0 SYS_exit : uintptr : 1 SYS_fork : uintptr : 2 @@ -1112,7 +1112,7 @@ when ODIN_ARCH == "amd64" { SYS_landlock_add_rule : uintptr : 445 SYS_landlock_restrict_self : uintptr : 446 SYS_memfd_secret : uintptr : 447 -} else when ODIN_ARCH == "arm" { +} else when false /*ODIN_ARCH == .arm*/ { // TODO SYS_restart_syscall : uintptr : 0 SYS_exit : uintptr : 1 SYS_fork : uintptr : 2 diff --git a/core/time/time_unix.odin b/core/time/time_unix.odin index 0d765b72d..9c5c5cc35 100644 --- a/core/time/time_unix.odin +++ b/core/time/time_unix.odin @@ -3,7 +3,7 @@ package time IS_SUPPORTED :: true // NOTE: Times on Darwin are UTC. -when ODIN_OS == "darwin" { +when ODIN_OS == .Darwin { foreign import libc "System.framework" } else { foreign import libc "system:c" diff --git a/src/checker.cpp b/src/checker.cpp index 63a697072..055d0d356 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -856,11 +856,42 @@ void init_universal(void) { add_global_bool_constant("false", false); // TODO(bill): Set through flags in the compiler - add_global_string_constant("ODIN_OS", bc->ODIN_OS); - add_global_string_constant("ODIN_ARCH", bc->ODIN_ARCH); add_global_string_constant("ODIN_VENDOR", bc->ODIN_VENDOR); add_global_string_constant("ODIN_VERSION", bc->ODIN_VERSION); add_global_string_constant("ODIN_ROOT", bc->ODIN_ROOT); + + { + GlobalEnumValue values[TargetOs_COUNT] = { + {"Unknown", TargetOs_Invalid}, + {"Windows", TargetOs_windows}, + {"Darwin", TargetOs_darwin}, + {"Linux", TargetOs_linux}, + {"Essence", TargetOs_essence}, + {"FreeBSD", TargetOs_freebsd}, + {"WASI", TargetOs_wasi}, + {"JS", TargetOs_js}, + {"Freestanding", TargetOs_freestanding}, + }; + + auto fields = add_global_enum_type(str_lit("Odin_OS_Type"), values, gb_count_of(values)); + add_global_enum_constant(fields, "ODIN_OS", bc->metrics.os); + add_global_string_constant("ODIN_OS_STRING", target_os_names[bc->metrics.os]); + } + + { + GlobalEnumValue values[TargetArch_COUNT] = { + {"Unknown", TargetArch_Invalid}, + {"amd64", TargetArch_amd64}, + {"i386", TargetArch_i386}, + {"arm64", TargetArch_arm64}, + {"wasm32", TargetArch_wasm32}, + {"wasm64", TargetArch_wasm64}, + }; + + auto fields = add_global_enum_type(str_lit("Odin_Arch_Type"), values, gb_count_of(values)); + add_global_enum_constant(fields, "ODIN_ARCH", bc->metrics.arch); + add_global_string_constant("ODIN_ARCH_STRING", target_arch_names[bc->metrics.arch]); + } { GlobalEnumValue values[BuildMode_COUNT] = { @@ -875,7 +906,6 @@ void init_universal(void) { add_global_enum_constant(fields, "ODIN_BUILD_MODE", bc->build_mode); } - add_global_string_constant("ODIN_ENDIAN_STRING", target_endian_names[target_endians[bc->metrics.arch]]); { GlobalEnumValue values[TargetEndian_COUNT] = { {"Unknown", TargetEndian_Invalid}, @@ -886,6 +916,7 @@ void init_universal(void) { auto fields = add_global_enum_type(str_lit("Odin_Endian_Type"), values, gb_count_of(values)); add_global_enum_constant(fields, "ODIN_ENDIAN", target_endians[bc->metrics.arch]); + add_global_string_constant("ODIN_ENDIAN_STRING", target_endian_names[target_endians[bc->metrics.arch]]); } diff --git a/vendor/ENet/enet.odin b/vendor/ENet/enet.odin index 8d068fbfc..37e65b497 100644 --- a/vendor/ENet/enet.odin +++ b/vendor/ENet/enet.odin @@ -1,7 +1,7 @@ package ENet -when ODIN_OS == "windows" { - when ODIN_ARCH == "amd64" { +when ODIN_OS == .Windows { + when ODIN_ARCH == .amd64 { foreign import ENet { "lib/enet64.lib", "system:Ws2_32.lib", diff --git a/vendor/OpenGL/helpers.odin b/vendor/OpenGL/helpers.odin index 0a9cffefa..661de318c 100644 --- a/vendor/OpenGL/helpers.odin +++ b/vendor/OpenGL/helpers.odin @@ -188,7 +188,7 @@ load_shaders_source :: proc(vs_source, fs_source: string, binary_retrievable := load_shaders :: proc{load_shaders_file} -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { update_shader_if_changed :: proc( vertex_name, fragment_name: string, program: u32, diff --git a/vendor/botan/bindings/botan.odin b/vendor/botan/bindings/botan.odin index d1d88cda0..fdddc99a9 100644 --- a/vendor/botan/bindings/botan.odin +++ b/vendor/botan/bindings/botan.odin @@ -136,11 +136,11 @@ totp_t :: ^totp_struct fpe_struct :: struct{} fpe_t :: ^fpe_struct -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { foreign import botan_lib "botan.lib" -} else when ODIN_OS == "linux" { +} else when ODIN_OS == .Linux { foreign import botan_lib "system:botan-2" -} else when ODIN_OS == "darwin" { +} else when ODIN_OS == .Darwin { foreign import botan_lib "system:botan-2" } diff --git a/vendor/glfw/bindings/bindings.odin b/vendor/glfw/bindings/bindings.odin index 84905f603..f4e39015e 100644 --- a/vendor/glfw/bindings/bindings.odin +++ b/vendor/glfw/bindings/bindings.odin @@ -3,9 +3,9 @@ package glfw_bindings import "core:c" import vk "vendor:vulkan" -when ODIN_OS == "linux" { foreign import glfw "system:glfw" } // TODO: Add the billion-or-so static libs to link to in linux -when ODIN_OS == "darwin" { foreign import glfw "system:glfw" } -when ODIN_OS == "windows" { +when ODIN_OS == .Linux { foreign import glfw "system:glfw" } // TODO: Add the billion-or-so static libs to link to in linux +when ODIN_OS == .Darwin { foreign import glfw "system:glfw" } +when ODIN_OS == .Windows { foreign import glfw { "../lib/glfw3_mt.lib", "system:user32.lib", diff --git a/vendor/glfw/native.odin b/vendor/glfw/native.odin index 871c42af9..902b30656 100644 --- a/vendor/glfw/native.odin +++ b/vendor/glfw/native.odin @@ -1,6 +1,6 @@ package glfw -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { import win32 "core:sys/windows" foreign import glfw { "lib/glfw3.lib", "system:user32.lib", "system:gdi32.lib", "system:shell32.lib" } @@ -12,7 +12,7 @@ when ODIN_OS == "windows" { GetWin32Window :: proc(window: WindowHandle) -> win32.HWND --- GetWGLContext :: proc(window: WindowHandle) -> rawptr --- } -} else when ODIN_OS == "linux" { +} else when ODIN_OS == .Linux { // TODO: Native Linux // Display* glfwGetX11Display(void); // RRCrtc glfwGetX11Adapter(GLFWmonitor* monitor); @@ -24,7 +24,7 @@ when ODIN_OS == "windows" { // struct wl_display* glfwGetWaylandDisplay(void); // struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* monitor); // struct wl_surface* glfwGetWaylandWindow(GLFWwindow* window); -} else when ODIN_OS == "darwin" { +} else when ODIN_OS == .Darwin { // TODO: Native Darwin // CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* monitor); // id glfwGetCocoaWindow(GLFWwindow* window); diff --git a/vendor/miniaudio/common.odin b/vendor/miniaudio/common.odin index 62e32e8b1..75b66101f 100644 --- a/vendor/miniaudio/common.odin +++ b/vendor/miniaudio/common.odin @@ -2,8 +2,8 @@ package miniaudio import "core:c" -when ODIN_OS == "windows" { foreign import lib "lib/miniaudio.lib" } -when ODIN_OS == "linux" { foreign import lib "lib/miniaudio.a" } +when ODIN_OS == .Windows { foreign import lib "lib/miniaudio.lib" } +when ODIN_OS == .Linux { foreign import lib "lib/miniaudio.a" } handle :: distinct rawptr @@ -270,7 +270,7 @@ thread_priority :: enum c.int { /* Spinlocks are 32-bit for compatibility reasons. */ spinlock :: distinct u32 -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { thread :: distinct rawptr mutex :: distinct rawptr event :: distinct rawptr diff --git a/vendor/miniaudio/data_conversion.odin b/vendor/miniaudio/data_conversion.odin index 1a5c9d265..8a53cc19e 100644 --- a/vendor/miniaudio/data_conversion.odin +++ b/vendor/miniaudio/data_conversion.odin @@ -2,8 +2,8 @@ package miniaudio import "core:c" -when ODIN_OS == "windows" { foreign import lib "lib/miniaudio.lib" } -when ODIN_OS == "linux" { foreign import lib "lib/miniaudio.a" } +when ODIN_OS == .Windows { foreign import lib "lib/miniaudio.lib" } +when ODIN_OS == .Linux { foreign import lib "lib/miniaudio.a" } /************************************************************************************************************************************************************ diff --git a/vendor/miniaudio/decoding.odin b/vendor/miniaudio/decoding.odin index cdddd06fe..52b315f10 100644 --- a/vendor/miniaudio/decoding.odin +++ b/vendor/miniaudio/decoding.odin @@ -2,8 +2,8 @@ package miniaudio import "core:c" -when ODIN_OS == "windows" { foreign import lib "lib/miniaudio.lib" } -when ODIN_OS == "linux" { foreign import lib "lib/miniaudio.a" } +when ODIN_OS == .Windows { foreign import lib "lib/miniaudio.lib" } +when ODIN_OS == .Linux { foreign import lib "lib/miniaudio.a" } diff --git a/vendor/miniaudio/device_io_procs.odin b/vendor/miniaudio/device_io_procs.odin index c9cfb7c04..8d6609186 100644 --- a/vendor/miniaudio/device_io_procs.odin +++ b/vendor/miniaudio/device_io_procs.odin @@ -1,7 +1,7 @@ package miniaudio -when ODIN_OS == "windows" { foreign import lib "lib/miniaudio.lib" } -when ODIN_OS == "linux" { foreign import lib "lib/miniaudio.a" } +when ODIN_OS == .Windows { foreign import lib "lib/miniaudio.lib" } +when ODIN_OS == .Linux { foreign import lib "lib/miniaudio.a" } import "core:c" diff --git a/vendor/miniaudio/device_io_types.odin b/vendor/miniaudio/device_io_types.odin index 8f43b8640..7778e85cf 100644 --- a/vendor/miniaudio/device_io_types.odin +++ b/vendor/miniaudio/device_io_types.odin @@ -2,21 +2,21 @@ package miniaudio import "core:c" -SUPPORT_WASAPI :: ODIN_OS == "windows" -SUPPORT_DSOUND :: ODIN_OS == "windows" -SUPPORT_WINMM :: ODIN_OS == "windows" -SUPPORT_COREAUDIO :: ODIN_OS == "darwin" -SUPPORT_SNDIO :: ODIN_OS == "openbsd" -SUPPORT_AUDIO4 :: ODIN_OS == "openbsd" || ODIN_OS == "netbsd" -SUPPORT_OSS :: ODIN_OS == "freebsd" -SUPPORT_PULSEAUDIO :: ODIN_OS == "linux" -SUPPORT_ALSA :: ODIN_OS == "linux" -SUPPORT_JACK :: ODIN_OS == "windows" -SUPPORT_AAUDIO :: ODIN_OS == "android" -SUPPORT_OPENSL :: ODIN_OS == "android" -SUPPORT_WEBAUDIO :: ODIN_OS == "emscripten" +SUPPORT_WASAPI :: ODIN_OS == .Windows +SUPPORT_DSOUND :: ODIN_OS == .Windows +SUPPORT_WINMM :: ODIN_OS == .Windows +SUPPORT_COREAUDIO :: ODIN_OS == .Darwin +SUPPORT_SNDIO :: false // ODIN_OS == .OpenBSD +SUPPORT_AUDIO4 :: false // ODIN_OS == .OpenBSD || ODIN_OS == .NetBSD +SUPPORT_OSS :: ODIN_OS == .FreeBSD +SUPPORT_PULSEAUDIO :: ODIN_OS == .Linux +SUPPORT_ALSA :: ODIN_OS == .Linux +SUPPORT_JACK :: ODIN_OS == .Windows +SUPPORT_AAUDIO :: false // ODIN_OS == .Android +SUPPORT_OPENSL :: false // ODIN_OS == .Android +SUPPORT_WEBAUDIO :: false // ODIN_OS == .Emscripten SUPPORT_CUSTOM :: true -SUPPORT_NULL :: ODIN_OS != "emscripten" +SUPPORT_NULL :: true // ODIN_OS != .Emscripten STATE_UNINITIALIZED :: 0 STATE_STOPPED :: 1 /* The device's default state after initialization. */ @@ -895,7 +895,7 @@ context_type :: struct { RegOpenKeyExA: proc "system" (), RegCloseKey: proc "system" (), RegQueryValueExA: proc "system" (), - } when ODIN_OS == "windows" else struct {}), + } when ODIN_OS == .Windows else struct {}), posix: (struct { pthreadSO: handle, @@ -914,7 +914,7 @@ context_type :: struct { pthread_attr_setschedpolicy: proc "system" (), pthread_attr_getschedparam: proc "system" (), pthread_attr_setschedparam: proc "system" (), - } when ODIN_OS != "windows" else struct {}), + } when ODIN_OS != .Windows else struct {}), _unused: c.int, }, diff --git a/vendor/miniaudio/encoding.odin b/vendor/miniaudio/encoding.odin index 866c19010..83f9d5252 100644 --- a/vendor/miniaudio/encoding.odin +++ b/vendor/miniaudio/encoding.odin @@ -2,8 +2,8 @@ package miniaudio import "core:c" -when ODIN_OS == "windows" { foreign import lib "lib/miniaudio.lib" } -when ODIN_OS == "linux" { foreign import lib "lib/miniaudio.a" } +when ODIN_OS == .Windows { foreign import lib "lib/miniaudio.lib" } +when ODIN_OS == .Linux { foreign import lib "lib/miniaudio.a" } /************************************************************************************************************************************************************ diff --git a/vendor/miniaudio/filtering.odin b/vendor/miniaudio/filtering.odin index fec21f33d..4956da173 100644 --- a/vendor/miniaudio/filtering.odin +++ b/vendor/miniaudio/filtering.odin @@ -1,7 +1,7 @@ package miniaudio -when ODIN_OS == "windows" { foreign import lib "lib/miniaudio.lib" } -when ODIN_OS == "linux" { foreign import lib "lib/miniaudio.a" } +when ODIN_OS == .Windows { foreign import lib "lib/miniaudio.lib" } +when ODIN_OS == .Linux { foreign import lib "lib/miniaudio.a" } /************************************************************************************************************************************************************** diff --git a/vendor/miniaudio/generation.odin b/vendor/miniaudio/generation.odin index c2009967c..c241f00b1 100644 --- a/vendor/miniaudio/generation.odin +++ b/vendor/miniaudio/generation.odin @@ -2,8 +2,8 @@ package miniaudio import "core:c" -when ODIN_OS == "windows" { foreign import lib "lib/miniaudio.lib" } -when ODIN_OS == "linux" { foreign import lib "lib/miniaudio.a" } +when ODIN_OS == .Windows { foreign import lib "lib/miniaudio.lib" } +when ODIN_OS == .Linux { foreign import lib "lib/miniaudio.a" } waveform_type :: enum c.int { sine, diff --git a/vendor/miniaudio/logging.odin b/vendor/miniaudio/logging.odin index 54792bff9..35aa54bc9 100644 --- a/vendor/miniaudio/logging.odin +++ b/vendor/miniaudio/logging.odin @@ -2,8 +2,8 @@ package miniaudio import c "core:c/libc" -when ODIN_OS == "windows" { foreign import lib "lib/miniaudio.lib" } -when ODIN_OS == "linux" { foreign import lib "lib/miniaudio.a" } +when ODIN_OS == .Windows { foreign import lib "lib/miniaudio.lib" } +when ODIN_OS == .Linux { foreign import lib "lib/miniaudio.a" } MAX_LOG_CALLBACKS :: 4 diff --git a/vendor/miniaudio/utilities.odin b/vendor/miniaudio/utilities.odin index 1a94550e4..19307a77d 100644 --- a/vendor/miniaudio/utilities.odin +++ b/vendor/miniaudio/utilities.odin @@ -1,7 +1,7 @@ package miniaudio -when ODIN_OS == "windows" { foreign import lib "lib/miniaudio.lib" } -when ODIN_OS == "linux" { foreign import lib "lib/miniaudio.a" } +when ODIN_OS == .Windows { foreign import lib "lib/miniaudio.lib" } +when ODIN_OS == .Linux { foreign import lib "lib/miniaudio.a" } @(default_calling_convention="c", link_prefix="ma_") foreign lib { diff --git a/vendor/miniaudio/vfs.odin b/vendor/miniaudio/vfs.odin index fa18afb6b..547fbd265 100644 --- a/vendor/miniaudio/vfs.odin +++ b/vendor/miniaudio/vfs.odin @@ -2,8 +2,8 @@ package miniaudio import "core:c" -when ODIN_OS == "windows" { foreign import lib "lib/miniaudio.lib" } -when ODIN_OS == "linux" { foreign import lib "lib/miniaudio.a" } +when ODIN_OS == .Windows { foreign import lib "lib/miniaudio.lib" } +when ODIN_OS == .Linux { foreign import lib "lib/miniaudio.a" } /************************************************************************************************************************************************************ diff --git a/vendor/portmidi/portmidi.odin b/vendor/portmidi/portmidi.odin index 08f78150c..40fd18b8b 100644 --- a/vendor/portmidi/portmidi.odin +++ b/vendor/portmidi/portmidi.odin @@ -3,7 +3,7 @@ package portmidi import "core:c" import "core:strings" -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { foreign import lib { "portmidi_s.lib", "system:Winmm.lib", diff --git a/vendor/portmidi/util.odin b/vendor/portmidi/util.odin index d02142bd0..ca2e1f4ca 100644 --- a/vendor/portmidi/util.odin +++ b/vendor/portmidi/util.odin @@ -7,7 +7,7 @@ package portmidi import "core:c" -when ODIN_OS == "windows" { foreign import lib "portmidi_s.lib" } +when ODIN_OS == .Windows { foreign import lib "portmidi_s.lib" } Queue :: distinct rawptr diff --git a/vendor/raylib/raylib.odin b/vendor/raylib/raylib.odin index fb4d7dd92..0c8248683 100644 --- a/vendor/raylib/raylib.odin +++ b/vendor/raylib/raylib.odin @@ -91,7 +91,7 @@ MAX_TEXT_BUFFER_LENGTH :: #config(RAYLIB_MAX_TEXT_BUFFER_LENGTH, 1024) #assert(size_of(rune) == size_of(c.int)) -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { foreign import lib { "raylib.lib", "system:Winmm.lib", @@ -100,14 +100,14 @@ when ODIN_OS == "windows" { "system:Shell32.lib", } } -when ODIN_OS == "linux" { +when ODIN_OS == .Linux { foreign import lib { "linux/libraylib.a", "system:dl", "system:pthread", } } -when ODIN_OS == "darwin" { foreign import lib "macos/libraylib.a" } +when ODIN_OS == .Darwin { foreign import lib "macos/libraylib.a" } VERSION :: "4.0" diff --git a/vendor/raylib/rlgl.odin b/vendor/raylib/rlgl.odin index 8f91486c1..936a34765 100644 --- a/vendor/raylib/rlgl.odin +++ b/vendor/raylib/rlgl.odin @@ -2,7 +2,7 @@ package raylib import "core:c" -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { foreign import lib { "raylib.lib", "system:Winmm.lib", @@ -11,8 +11,8 @@ when ODIN_OS == "windows" { "system:Shell32.lib", } } -when ODIN_OS == "linux" { foreign import lib "linux/libraylib.a" } -when ODIN_OS == "darwin" { foreign import lib "macos/libraylib.a" } +when ODIN_OS == .Linux { foreign import lib "linux/libraylib.a" } +when ODIN_OS == .Darwin { foreign import lib "macos/libraylib.a" } GRAPHICS_API_OPENGL_11 :: false GRAPHICS_API_OPENGL_21 :: true diff --git a/vendor/sdl2/image/sdl_image.odin b/vendor/sdl2/image/sdl_image.odin index 1dbe048ed..30a7db6a8 100644 --- a/vendor/sdl2/image/sdl_image.odin +++ b/vendor/sdl2/image/sdl_image.odin @@ -3,10 +3,10 @@ package sdl2_image import "core:c" import SDL ".." -when ODIN_OS == "windows" { foreign import lib "SDL2_image.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2_image" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2_image" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2_image" } +when ODIN_OS == .Windows { foreign import lib "SDL2_image.lib" } +when ODIN_OS == .Linux { foreign import lib "system:SDL2_image" } +when ODIN_OS == .Darwin { foreign import lib "system:SDL2_image" } +when ODIN_OS == .FreeBSD { foreign import lib "system:SDL2_image" } bool :: SDL.bool diff --git a/vendor/sdl2/mixer/sdl_mixer.odin b/vendor/sdl2/mixer/sdl_mixer.odin index 90334d91a..7fa3f216f 100644 --- a/vendor/sdl2/mixer/sdl_mixer.odin +++ b/vendor/sdl2/mixer/sdl_mixer.odin @@ -3,10 +3,10 @@ package sdl2_mixer import "core:c" import SDL ".." -when ODIN_OS == "windows" { foreign import lib "SDL2_mixer.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2_mixer" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2_mixer" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2_mixer" } +when ODIN_OS == .Windows { foreign import lib "SDL2_mixer.lib" } +when ODIN_OS == .Linux { foreign import lib "system:SDL2_mixer" } +when ODIN_OS == .Darwin { foreign import lib "system:SDL2_mixer" } +when ODIN_OS == .FreeBSD { foreign import lib "system:SDL2_mixer" } MAJOR_VERSION :: 2 diff --git a/vendor/sdl2/net/sdl_net.odin b/vendor/sdl2/net/sdl_net.odin index 49671764a..b3e2c2e62 100644 --- a/vendor/sdl2/net/sdl_net.odin +++ b/vendor/sdl2/net/sdl_net.odin @@ -3,10 +3,10 @@ package sdl2_net import "core:c" import SDL ".." -when ODIN_OS == "windows" { foreign import lib "SDL2_net.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2_net" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2_net" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2_net" } +when ODIN_OS == .Windows { foreign import lib "SDL2_net.lib" } +when ODIN_OS == .Linux { foreign import lib "system:SDL2_net" } +when ODIN_OS == .Darwin { foreign import lib "system:SDL2_net" } +when ODIN_OS == .FreeBSD { foreign import lib "system:SDL2_net" } bool :: SDL.bool diff --git a/vendor/sdl2/sdl2.odin b/vendor/sdl2/sdl2.odin index 4781483f7..e36c002dd 100644 --- a/vendor/sdl2/sdl2.odin +++ b/vendor/sdl2/sdl2.odin @@ -25,10 +25,10 @@ package sdl2 import "core:c" import "core:intrinsics" -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { foreign import lib "SDL2.lib" } +when ODIN_OS == .Linux { foreign import lib "system:SDL2" } +when ODIN_OS == .Darwin { foreign import lib "system:SDL2" } +when ODIN_OS == .FreeBSD { foreign import lib "system:SDL2" } version :: struct { major: u8, /**< major version */ diff --git a/vendor/sdl2/sdl_audio.odin b/vendor/sdl2/sdl_audio.odin index 2c5b7fedb..a03031165 100644 --- a/vendor/sdl2/sdl_audio.odin +++ b/vendor/sdl2/sdl_audio.odin @@ -2,10 +2,10 @@ package sdl2 import "core:c" -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { foreign import lib "SDL2.lib" } +when ODIN_OS == .Linux { foreign import lib "system:SDL2" } +when ODIN_OS == .Darwin { foreign import lib "system:SDL2" } +when ODIN_OS == .FreeBSD { foreign import lib "system:SDL2" } /** * \brief Audio format flags. diff --git a/vendor/sdl2/sdl_blendmode.odin b/vendor/sdl2/sdl_blendmode.odin index 3fb7c2e83..525cf0f38 100644 --- a/vendor/sdl2/sdl_blendmode.odin +++ b/vendor/sdl2/sdl_blendmode.odin @@ -2,10 +2,10 @@ package sdl2 import "core:c" -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { foreign import lib "SDL2.lib" } +when ODIN_OS == .Linux { foreign import lib "system:SDL2" } +when ODIN_OS == .Darwin { foreign import lib "system:SDL2" } +when ODIN_OS == .FreeBSD { foreign import lib "system:SDL2" } /** * \brief The blend mode used in SDL_RenderCopy() and drawing operations. diff --git a/vendor/sdl2/sdl_cpuinfo.odin b/vendor/sdl2/sdl_cpuinfo.odin index 5fe5cf16c..7d2e681fe 100644 --- a/vendor/sdl2/sdl_cpuinfo.odin +++ b/vendor/sdl2/sdl_cpuinfo.odin @@ -2,10 +2,10 @@ package sdl2 import "core:c" -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { foreign import lib "SDL2.lib" } +when ODIN_OS == .Linux { foreign import lib "system:SDL2" } +when ODIN_OS == .Darwin { foreign import lib "system:SDL2" } +when ODIN_OS == .FreeBSD { foreign import lib "system:SDL2" } /* This is a guess for the cacheline size used for padding. * Most x86 processors have a 64 byte cache line. diff --git a/vendor/sdl2/sdl_events.odin b/vendor/sdl2/sdl_events.odin index 535269656..3f58b51c3 100644 --- a/vendor/sdl2/sdl_events.odin +++ b/vendor/sdl2/sdl_events.odin @@ -2,10 +2,10 @@ package sdl2 import "core:c" -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { foreign import lib "SDL2.lib" } +when ODIN_OS == .Linux { foreign import lib "system:SDL2" } +when ODIN_OS == .Darwin { foreign import lib "system:SDL2" } +when ODIN_OS == .FreeBSD { foreign import lib "system:SDL2" } RELEASED :: 0 PRESSED :: 1 diff --git a/vendor/sdl2/sdl_gamecontroller.odin b/vendor/sdl2/sdl_gamecontroller.odin index 747cd1af6..9fef6b1ab 100644 --- a/vendor/sdl2/sdl_gamecontroller.odin +++ b/vendor/sdl2/sdl_gamecontroller.odin @@ -2,10 +2,10 @@ package sdl2 import "core:c" -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { foreign import lib "SDL2.lib" } +when ODIN_OS == .Linux { foreign import lib "system:SDL2" } +when ODIN_OS == .Darwin { foreign import lib "system:SDL2" } +when ODIN_OS == .FreeBSD { foreign import lib "system:SDL2" } GameController :: struct {} diff --git a/vendor/sdl2/sdl_gesture_haptic.odin b/vendor/sdl2/sdl_gesture_haptic.odin index 0d257a525..1c8616e99 100644 --- a/vendor/sdl2/sdl_gesture_haptic.odin +++ b/vendor/sdl2/sdl_gesture_haptic.odin @@ -2,10 +2,10 @@ package sdl2 import "core:c" -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { foreign import lib "SDL2.lib" } +when ODIN_OS == .Linux { foreign import lib "system:SDL2" } +when ODIN_OS == .Darwin { foreign import lib "system:SDL2" } +when ODIN_OS == .FreeBSD { foreign import lib "system:SDL2" } // Gesture diff --git a/vendor/sdl2/sdl_hints.odin b/vendor/sdl2/sdl_hints.odin index b5793bb02..a84e5a090 100644 --- a/vendor/sdl2/sdl_hints.odin +++ b/vendor/sdl2/sdl_hints.odin @@ -2,10 +2,10 @@ package sdl2 import "core:c" -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { foreign import lib "SDL2.lib" } +when ODIN_OS == .Linux { foreign import lib "system:SDL2" } +when ODIN_OS == .Darwin { foreign import lib "system:SDL2" } +when ODIN_OS == .FreeBSD { foreign import lib "system:SDL2" } HINT_ACCELEROMETER_AS_JOYSTICK :: "SDL_ACCELEROMETER_AS_JOYSTICK" HINT_ALLOW_ALT_TAB_WHILE_GRABBED :: "SDL_ALLOW_ALT_TAB_WHILE_GRABBED" diff --git a/vendor/sdl2/sdl_joystick.odin b/vendor/sdl2/sdl_joystick.odin index d2bb624b7..1178eae24 100644 --- a/vendor/sdl2/sdl_joystick.odin +++ b/vendor/sdl2/sdl_joystick.odin @@ -2,10 +2,10 @@ package sdl2 import "core:c" -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { foreign import lib "SDL2.lib" } +when ODIN_OS == .Linux { foreign import lib "system:SDL2" } +when ODIN_OS == .Darwin { foreign import lib "system:SDL2" } +when ODIN_OS == .FreeBSD { foreign import lib "system:SDL2" } Joystick :: struct {} diff --git a/vendor/sdl2/sdl_keyboard.odin b/vendor/sdl2/sdl_keyboard.odin index 86112863a..a68c644ab 100644 --- a/vendor/sdl2/sdl_keyboard.odin +++ b/vendor/sdl2/sdl_keyboard.odin @@ -2,10 +2,10 @@ package sdl2 import "core:c" -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { foreign import lib "SDL2.lib" } +when ODIN_OS == .Linux { foreign import lib "system:SDL2" } +when ODIN_OS == .Darwin { foreign import lib "system:SDL2" } +when ODIN_OS == .FreeBSD { foreign import lib "system:SDL2" } Keysym :: struct { scancode: Scancode, /**< SDL physical key code - see ::SDL_Scancode for details */ diff --git a/vendor/sdl2/sdl_log.odin b/vendor/sdl2/sdl_log.odin index b9f8a8d7d..d42d82b77 100644 --- a/vendor/sdl2/sdl_log.odin +++ b/vendor/sdl2/sdl_log.odin @@ -2,10 +2,10 @@ package sdl2 import "core:c" -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { foreign import lib "SDL2.lib" } +when ODIN_OS == .Linux { foreign import lib "system:SDL2" } +when ODIN_OS == .Darwin { foreign import lib "system:SDL2" } +when ODIN_OS == .FreeBSD { foreign import lib "system:SDL2" } MAX_LOG_MESSAGE :: 4096 diff --git a/vendor/sdl2/sdl_messagebox.odin b/vendor/sdl2/sdl_messagebox.odin index d8a07c1e2..c66cc4911 100644 --- a/vendor/sdl2/sdl_messagebox.odin +++ b/vendor/sdl2/sdl_messagebox.odin @@ -2,10 +2,10 @@ package sdl2 import "core:c" -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { foreign import lib "SDL2.lib" } +when ODIN_OS == .Linux { foreign import lib "system:SDL2" } +when ODIN_OS == .Darwin { foreign import lib "system:SDL2" } +when ODIN_OS == .FreeBSD { foreign import lib "system:SDL2" } MessageBoxFlag :: enum u32 { _ = 0, diff --git a/vendor/sdl2/sdl_metal.odin b/vendor/sdl2/sdl_metal.odin index 87a0313ef..953c6d45f 100644 --- a/vendor/sdl2/sdl_metal.odin +++ b/vendor/sdl2/sdl_metal.odin @@ -2,10 +2,10 @@ package sdl2 import "core:c" -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { foreign import lib "SDL2.lib" } +when ODIN_OS == .Linux { foreign import lib "system:SDL2" } +when ODIN_OS == .Darwin { foreign import lib "system:SDL2" } +when ODIN_OS == .FreeBSD { foreign import lib "system:SDL2" } MetalView :: distinct rawptr diff --git a/vendor/sdl2/sdl_mouse.odin b/vendor/sdl2/sdl_mouse.odin index d667addc8..5ca8d9b5e 100644 --- a/vendor/sdl2/sdl_mouse.odin +++ b/vendor/sdl2/sdl_mouse.odin @@ -2,10 +2,10 @@ package sdl2 import "core:c" -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { foreign import lib "SDL2.lib" } +when ODIN_OS == .Linux { foreign import lib "system:SDL2" } +when ODIN_OS == .Darwin { foreign import lib "system:SDL2" } +when ODIN_OS == .FreeBSD { foreign import lib "system:SDL2" } Cursor :: struct {} diff --git a/vendor/sdl2/sdl_mutex.odin b/vendor/sdl2/sdl_mutex.odin index 80d62f7c8..6b9c96319 100644 --- a/vendor/sdl2/sdl_mutex.odin +++ b/vendor/sdl2/sdl_mutex.odin @@ -2,10 +2,10 @@ package sdl2 import "core:c" -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { foreign import lib "SDL2.lib" } +when ODIN_OS == .Linux { foreign import lib "system:SDL2" } +when ODIN_OS == .Darwin { foreign import lib "system:SDL2" } +when ODIN_OS == .FreeBSD { foreign import lib "system:SDL2" } MUTEX_TIMEDOUT :: 1 MUTEX_MAXWAIT :: ~u32(0) diff --git a/vendor/sdl2/sdl_pixels.odin b/vendor/sdl2/sdl_pixels.odin index 22f6db440..3cd2da5f4 100644 --- a/vendor/sdl2/sdl_pixels.odin +++ b/vendor/sdl2/sdl_pixels.odin @@ -2,10 +2,10 @@ package sdl2 import "core:c" -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { foreign import lib "SDL2.lib" } +when ODIN_OS == .Linux { foreign import lib "system:SDL2" } +when ODIN_OS == .Darwin { foreign import lib "system:SDL2" } +when ODIN_OS == .FreeBSD { foreign import lib "system:SDL2" } ALPHA_OPAQUE :: 255 ALPHA_TRANSPARENT :: 0 diff --git a/vendor/sdl2/sdl_rect.odin b/vendor/sdl2/sdl_rect.odin index 929897c26..b0d6242be 100644 --- a/vendor/sdl2/sdl_rect.odin +++ b/vendor/sdl2/sdl_rect.odin @@ -2,10 +2,10 @@ package sdl2 import "core:c" -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { foreign import lib "SDL2.lib" } +when ODIN_OS == .Linux { foreign import lib "system:SDL2" } +when ODIN_OS == .Darwin { foreign import lib "system:SDL2" } +when ODIN_OS == .FreeBSD { foreign import lib "system:SDL2" } Point :: struct { x: c.int, diff --git a/vendor/sdl2/sdl_render.odin b/vendor/sdl2/sdl_render.odin index c92fd3eda..435c40570 100644 --- a/vendor/sdl2/sdl_render.odin +++ b/vendor/sdl2/sdl_render.odin @@ -2,10 +2,10 @@ package sdl2 import "core:c" -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { foreign import lib "SDL2.lib" } +when ODIN_OS == .Linux { foreign import lib "system:SDL2" } +when ODIN_OS == .Darwin { foreign import lib "system:SDL2" } +when ODIN_OS == .FreeBSD { foreign import lib "system:SDL2" } RendererFlag :: enum u32 { SOFTWARE = 0, /**< The renderer is a software fallback */ diff --git a/vendor/sdl2/sdl_rwops.odin b/vendor/sdl2/sdl_rwops.odin index 590815c90..3bee66290 100644 --- a/vendor/sdl2/sdl_rwops.odin +++ b/vendor/sdl2/sdl_rwops.odin @@ -2,10 +2,10 @@ package sdl2 import "core:c" -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { foreign import lib "SDL2.lib" } +when ODIN_OS == .Linux { foreign import lib "system:SDL2" } +when ODIN_OS == .Darwin { foreign import lib "system:SDL2" } +when ODIN_OS == .FreeBSD { foreign import lib "system:SDL2" } /* RWops Types */ RWOPS_UNKNOWN :: 0 /**< Unknown stream type */ diff --git a/vendor/sdl2/sdl_stdinc.odin b/vendor/sdl2/sdl_stdinc.odin index bf098a591..9bd5df4da 100644 --- a/vendor/sdl2/sdl_stdinc.odin +++ b/vendor/sdl2/sdl_stdinc.odin @@ -5,10 +5,10 @@ import "core:intrinsics" import "core:runtime" _, _ :: intrinsics, runtime -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { foreign import lib "SDL2.lib" } +when ODIN_OS == .Linux { foreign import lib "system:SDL2" } +when ODIN_OS == .Darwin { foreign import lib "system:SDL2" } +when ODIN_OS == .FreeBSD { foreign import lib "system:SDL2" } bool :: distinct b32 #assert(size_of(bool) == size_of(c.int)) diff --git a/vendor/sdl2/sdl_surface.odin b/vendor/sdl2/sdl_surface.odin index c0b20be63..e5a5da7ef 100644 --- a/vendor/sdl2/sdl_surface.odin +++ b/vendor/sdl2/sdl_surface.odin @@ -2,10 +2,10 @@ package sdl2 import "core:c" -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { foreign import lib "SDL2.lib" } +when ODIN_OS == .Linux { foreign import lib "system:SDL2" } +when ODIN_OS == .Darwin { foreign import lib "system:SDL2" } +when ODIN_OS == .FreeBSD { foreign import lib "system:SDL2" } SWSURFACE :: 0 /**< Just here for compatibility */ PREALLOC :: 0x00000001 /**< Surface uses preallocated memory */ diff --git a/vendor/sdl2/sdl_system.odin b/vendor/sdl2/sdl_system.odin index 31f1b590b..89ae4c707 100644 --- a/vendor/sdl2/sdl_system.odin +++ b/vendor/sdl2/sdl_system.odin @@ -2,10 +2,10 @@ package sdl2 import "core:c" -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { foreign import lib "SDL2.lib" } +when ODIN_OS == .Linux { foreign import lib "system:SDL2" } +when ODIN_OS == .Darwin { foreign import lib "system:SDL2" } +when ODIN_OS == .FreeBSD { foreign import lib "system:SDL2" } // General @(default_calling_convention="c", link_prefix="SDL_") diff --git a/vendor/sdl2/sdl_syswm.odin b/vendor/sdl2/sdl_syswm.odin index e374e72b7..37da1d298 100644 --- a/vendor/sdl2/sdl_syswm.odin +++ b/vendor/sdl2/sdl_syswm.odin @@ -2,10 +2,10 @@ package sdl2 import "core:c" -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { foreign import lib "SDL2.lib" } +when ODIN_OS == .Linux { foreign import lib "system:SDL2" } +when ODIN_OS == .Darwin { foreign import lib "system:SDL2" } +when ODIN_OS == .FreeBSD { foreign import lib "system:SDL2" } SYSWM_TYPE :: enum c.int { UNKNOWN, diff --git a/vendor/sdl2/sdl_thread.odin b/vendor/sdl2/sdl_thread.odin index cbaf3ac00..98354438b 100644 --- a/vendor/sdl2/sdl_thread.odin +++ b/vendor/sdl2/sdl_thread.odin @@ -2,10 +2,10 @@ package sdl2 import "core:c" -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { foreign import lib "SDL2.lib" } +when ODIN_OS == .Linux { foreign import lib "system:SDL2" } +when ODIN_OS == .Darwin { foreign import lib "system:SDL2" } +when ODIN_OS == .FreeBSD { foreign import lib "system:SDL2" } Thread :: struct {} diff --git a/vendor/sdl2/sdl_timer.odin b/vendor/sdl2/sdl_timer.odin index 5b26c7346..357fdd437 100644 --- a/vendor/sdl2/sdl_timer.odin +++ b/vendor/sdl2/sdl_timer.odin @@ -2,10 +2,10 @@ package sdl2 import "core:c" -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { foreign import lib "SDL2.lib" } +when ODIN_OS == .Linux { foreign import lib "system:SDL2" } +when ODIN_OS == .Darwin { foreign import lib "system:SDL2" } +when ODIN_OS == .FreeBSD { foreign import lib "system:SDL2" } TimerCallback :: proc "c" (interval: u32, param: rawptr) -> u32 TimerID :: distinct c.int diff --git a/vendor/sdl2/sdl_touch.odin b/vendor/sdl2/sdl_touch.odin index c393b74ef..d90939cb9 100644 --- a/vendor/sdl2/sdl_touch.odin +++ b/vendor/sdl2/sdl_touch.odin @@ -2,10 +2,10 @@ package sdl2 import "core:c" -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { foreign import lib "SDL2.lib" } +when ODIN_OS == .Linux { foreign import lib "system:SDL2" } +when ODIN_OS == .Darwin { foreign import lib "system:SDL2" } +when ODIN_OS == .FreeBSD { foreign import lib "system:SDL2" } TouchID :: distinct i64 FingerID :: distinct i64 diff --git a/vendor/sdl2/sdl_video.odin b/vendor/sdl2/sdl_video.odin index 97a134739..01aaee1e7 100644 --- a/vendor/sdl2/sdl_video.odin +++ b/vendor/sdl2/sdl_video.odin @@ -2,10 +2,10 @@ package sdl2 import "core:c" -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { foreign import lib "SDL2.lib" } +when ODIN_OS == .Linux { foreign import lib "system:SDL2" } +when ODIN_OS == .Darwin { foreign import lib "system:SDL2" } +when ODIN_OS == .FreeBSD { foreign import lib "system:SDL2" } DisplayMode :: struct { format: u32, /**< pixel format */ diff --git a/vendor/sdl2/sdl_vulkan.odin b/vendor/sdl2/sdl_vulkan.odin index 97a41bacf..66b054524 100644 --- a/vendor/sdl2/sdl_vulkan.odin +++ b/vendor/sdl2/sdl_vulkan.odin @@ -3,10 +3,10 @@ package sdl2 import "core:c" import vk "vendor:vulkan" -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { foreign import lib "SDL2.lib" } +when ODIN_OS == .Linux { foreign import lib "system:SDL2" } +when ODIN_OS == .Darwin { foreign import lib "system:SDL2" } +when ODIN_OS == .FreeBSD { foreign import lib "system:SDL2" } VkInstance :: vk.Instance VkSurfaceKHR :: vk.SurfaceKHR diff --git a/vendor/sdl2/ttf/sdl_ttf.odin b/vendor/sdl2/ttf/sdl_ttf.odin index 6b41f07c2..20db09729 100644 --- a/vendor/sdl2/ttf/sdl_ttf.odin +++ b/vendor/sdl2/ttf/sdl_ttf.odin @@ -3,10 +3,10 @@ package sdl2_ttf import "core:c" import SDL ".." -when ODIN_OS == "windows" { foreign import lib "SDL2_ttf.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2_ttf" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2_ttf" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2_ttf" } +when ODIN_OS == .Windows { foreign import lib "SDL2_ttf.lib" } +when ODIN_OS == .Linux { foreign import lib "system:SDL2_ttf" } +when ODIN_OS == .Darwin { foreign import lib "system:SDL2_ttf" } +when ODIN_OS == .FreeBSD { foreign import lib "system:SDL2_ttf" } bool :: SDL.bool diff --git a/vendor/stb/image/stb_image.odin b/vendor/stb/image/stb_image.odin index 9e72760ab..8a3582792 100644 --- a/vendor/stb/image/stb_image.odin +++ b/vendor/stb/image/stb_image.odin @@ -4,8 +4,8 @@ import c "core:c/libc" #assert(size_of(c.int) == size_of(b32)) -when ODIN_OS == "windows" { foreign import stbi "../lib/stb_image.lib" } -when ODIN_OS == "linux" { foreign import stbi "../lib/stb_image.a" } +when ODIN_OS == .Windows { foreign import stbi "../lib/stb_image.lib" } +when ODIN_OS == .Linux { foreign import stbi "../lib/stb_image.a" } #assert(size_of(b32) == size_of(c.int)) diff --git a/vendor/stb/image/stb_image_resize.odin b/vendor/stb/image/stb_image_resize.odin index bee29a15e..65bf3e4a9 100644 --- a/vendor/stb/image/stb_image_resize.odin +++ b/vendor/stb/image/stb_image_resize.odin @@ -2,8 +2,8 @@ package stb_image import c "core:c/libc" -when ODIN_OS == "windows" { foreign import lib "../lib/stb_image_resize.lib" } -when ODIN_OS == "linux" { foreign import lib "../lib/stb_image_resize.a" } +when ODIN_OS == .Windows { foreign import lib "../lib/stb_image_resize.lib" } +when ODIN_OS == .Linux { foreign import lib "../lib/stb_image_resize.a" } ////////////////////////////////////////////////////////////////////////////// // diff --git a/vendor/stb/image/stb_image_write.odin b/vendor/stb/image/stb_image_write.odin index 1f0cfce85..67f4299fa 100644 --- a/vendor/stb/image/stb_image_write.odin +++ b/vendor/stb/image/stb_image_write.odin @@ -2,8 +2,8 @@ package stb_image import c "core:c/libc" -when ODIN_OS == "windows" { foreign import stbiw "../lib/stb_image_write.lib" } -when ODIN_OS == "linux" { foreign import stbiw "../lib/stb_image_write.a" } +when ODIN_OS == .Windows { foreign import stbiw "../lib/stb_image_write.lib" } +when ODIN_OS == .Linux { foreign import stbiw "../lib/stb_image_write.a" } write_func :: proc "c" (ctx: rawptr, data: rawptr, size: c.int) diff --git a/vendor/stb/rect_pack/stb_rect_pack.odin b/vendor/stb/rect_pack/stb_rect_pack.odin index 4142a73ec..f84f1cedc 100644 --- a/vendor/stb/rect_pack/stb_rect_pack.odin +++ b/vendor/stb/rect_pack/stb_rect_pack.odin @@ -4,8 +4,8 @@ import c "core:c/libc" #assert(size_of(b32) == size_of(c.int)) -when ODIN_OS == "windows" { foreign import lib "../lib/stb_rect_pack.lib" } -when ODIN_OS == "linux" { foreign import lib "../lib/stb_rect_pack.a" } +when ODIN_OS == .Windows { foreign import lib "../lib/stb_rect_pack.lib" } +when ODIN_OS == .Linux { foreign import lib "../lib/stb_rect_pack.a" } Coord :: distinct c.int _MAXVAL :: max(Coord) diff --git a/vendor/stb/truetype/stb_truetype.odin b/vendor/stb/truetype/stb_truetype.odin index 3abb187c2..cf4af15e9 100644 --- a/vendor/stb/truetype/stb_truetype.odin +++ b/vendor/stb/truetype/stb_truetype.odin @@ -3,8 +3,8 @@ package stb_truetype import c "core:c" import stbrp "vendor:stb/rect_pack" -when ODIN_OS == "windows" { foreign import stbtt "../lib/stb_truetype.lib" } -when ODIN_OS == "linux" { foreign import stbtt "../lib/stb_truetype.a" } +when ODIN_OS == .Windows { foreign import stbtt "../lib/stb_truetype.lib" } +when ODIN_OS == .Linux { foreign import stbtt "../lib/stb_truetype.a" } /////////////////////////////////////////////////////////////////////////////// diff --git a/vendor/stb/vorbis/stb_vorbis.odin b/vendor/stb/vorbis/stb_vorbis.odin index 7ec248df5..f35b58e04 100644 --- a/vendor/stb/vorbis/stb_vorbis.odin +++ b/vendor/stb/vorbis/stb_vorbis.odin @@ -3,8 +3,8 @@ package stb_vorbis import c "core:c/libc" -when ODIN_OS == "windows" { foreign import lib "../lib/stb_vorbis.lib" } -when ODIN_OS == "linux" { foreign import lib "../lib/stb_vorbis.a" } +when ODIN_OS == .Windows { foreign import lib "../lib/stb_vorbis.lib" } +when ODIN_OS == .Linux { foreign import lib "../lib/stb_vorbis.a" } diff --git a/vendor/vulkan/_gen/create_vulkan_odin_wrapper.py b/vendor/vulkan/_gen/create_vulkan_odin_wrapper.py index 1525f4e15..e7fb234c8 100644 --- a/vendor/vulkan/_gen/create_vulkan_odin_wrapper.py +++ b/vendor/vulkan/_gen/create_vulkan_odin_wrapper.py @@ -591,7 +591,7 @@ MAX_GLOBAL_PRIORITY_SIZE_EXT :: 16 f.write(""" import "core:c" -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { \timport win32 "core:sys/windows" \tHINSTANCE :: win32.HINSTANCE diff --git a/vendor/vulkan/structs.odin b/vendor/vulkan/structs.odin index 4d90a53fa..3c655a4fa 100644 --- a/vendor/vulkan/structs.odin +++ b/vendor/vulkan/structs.odin @@ -5,7 +5,7 @@ package vulkan import "core:c" -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { import win32 "core:sys/windows" HINSTANCE :: win32.HINSTANCE -- cgit v1.2.3 From 56b4e0a3c393dd0d820b4d82467c33e0e72298a6 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 23 Jan 2022 15:40:46 +0000 Subject: Fix #1267 --- src/check_expr.cpp | 3 ++- src/checker.cpp | 24 ++++++++++++++++++------ src/error.cpp | 1 + src/llvm_backend_type.cpp | 11 +++++------ src/ptr_set.cpp | 9 +++++++++ 5 files changed, 35 insertions(+), 13 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 8667d8734..99d351753 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -6085,7 +6085,8 @@ CallArgumentError check_polymorphic_record_type(CheckerContext *c, Operand *oper } // NOTE(bill): Add type info the parameters - add_type_info_type(c, o->type); + // TODO(bill, 2022-01-23): why was this line added in the first place? I'm commenting it out for the time being + // add_type_info_type(c, o->type); } { diff --git a/src/checker.cpp b/src/checker.cpp index 63a697072..55a3892e5 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -688,12 +688,17 @@ void add_dependency(CheckerInfo *info, DeclInfo *d, Entity *e) { ptr_set_add(&d->deps, e); mutex_unlock(&info->deps_mutex); } -void add_type_info_dependency(DeclInfo *d, Type *type) { +void add_type_info_dependency(CheckerInfo *info, DeclInfo *d, Type *type, bool require_mutex) { if (d == nullptr) { return; } - // NOTE(bill): no mutex is required here because the only procedure calling it is wrapped in a mutex already + if (require_mutex) { + mutex_lock(&info->deps_mutex); + } ptr_set_add(&d->type_info_deps, type); + if (require_mutex) { + mutex_unlock(&info->deps_mutex); + } } AstPackage *get_core_package(CheckerInfo *info, String name) { @@ -1589,7 +1594,7 @@ void add_type_info_type_internal(CheckerContext *c, Type *t) { return; } - add_type_info_dependency(c->decl, t); + add_type_info_dependency(c->info, c->decl, t, false); auto found = map_get(&c->info->type_info_map, t); if (found != nullptr) { @@ -1613,6 +1618,9 @@ void add_type_info_type_internal(CheckerContext *c, Type *t) { // NOTE(bill): map entries grow linearly and in order ti_index = c->info->type_info_types.count; array_add(&c->info->type_info_types, t); + if (t->kind == Type_Named && t->Named.name == "A") { + gb_printf_err("HERE!\n"); + } } map_set(&c->checker->info.type_info_map, t, ti_index); @@ -1718,6 +1726,7 @@ void add_type_info_type_internal(CheckerContext *c, Type *t) { } else { add_type_info_type_internal(c, t_type_info_ptr); } + add_type_info_type_internal(c, bt->Union.polymorphic_params); for_array(i, bt->Union.variants) { add_type_info_type_internal(c, bt->Union.variants[i]); } @@ -1741,6 +1750,7 @@ void add_type_info_type_internal(CheckerContext *c, Type *t) { } } } + add_type_info_type_internal(c, bt->Struct.polymorphic_params); for_array(i, bt->Struct.fields) { Entity *f = bt->Struct.fields[i]; add_type_info_type_internal(c, f->type); @@ -1934,6 +1944,7 @@ void add_min_dep_type_info(Checker *c, Type *t) { } else { add_min_dep_type_info(c, t_type_info_ptr); } + add_min_dep_type_info(c, bt->Union.polymorphic_params); for_array(i, bt->Union.variants) { add_min_dep_type_info(c, bt->Union.variants[i]); } @@ -1957,6 +1968,7 @@ void add_min_dep_type_info(Checker *c, Type *t) { } } } + add_min_dep_type_info(c, bt->Struct.polymorphic_params); for_array(i, bt->Struct.fields) { Entity *f = bt->Struct.fields[i]; add_min_dep_type_info(c, f->type); @@ -5473,9 +5485,6 @@ void check_parsed_files(Checker *c) { TIME_SECTION("calculate global init order"); calculate_global_init_order(c); - TIME_SECTION("generate minimum dependency set"); - generate_minimum_dependency_set(c, c->info.entry_point); - TIME_SECTION("check test procedures"); check_test_procedures(c); @@ -5486,6 +5495,9 @@ void check_parsed_files(Checker *c) { add_type_info_for_type_definitions(c); check_merge_queues_into_arrays(c); + TIME_SECTION("generate minimum dependency set"); + generate_minimum_dependency_set(c, c->info.entry_point); + TIME_SECTION("check entry point"); if (build_context.build_mode == BuildMode_Executable && !build_context.no_entry_point && build_context.command_kind != Command_test) { Scope *s = c->info.init_scope; diff --git a/src/error.cpp b/src/error.cpp index 1496b4775..b08ff99df 100644 --- a/src/error.cpp +++ b/src/error.cpp @@ -403,6 +403,7 @@ void compiler_error(char const *fmt, ...) { gb_printf_err("Internal Compiler Error: %s\n", gb_bprintf_va(fmt, va)); va_end(va); + GB_DEBUG_TRAP(); gb_exit(1); } diff --git a/src/llvm_backend_type.cpp b/src/llvm_backend_type.cpp index decb57702..e1332c6f3 100644 --- a/src/llvm_backend_type.cpp +++ b/src/llvm_backend_type.cpp @@ -1,11 +1,10 @@ isize lb_type_info_index(CheckerInfo *info, Type *type, bool err_on_not_found=true) { - isize index = type_info_index(info, type, false); + auto *set = &info->minimum_dependency_type_info_set; + isize index = type_info_index(info, type, err_on_not_found); if (index >= 0) { - auto *set = &info->minimum_dependency_type_info_set; - for_array(i, set->entries) { - if (set->entries[i].ptr == index) { - return i+1; - } + isize i = ptr_entry_index(set, index); + if (i >= 0) { + return i+1; } } if (err_on_not_found) { diff --git a/src/ptr_set.cpp b/src/ptr_set.cpp index ca7df3b53..b45997916 100644 --- a/src/ptr_set.cpp +++ b/src/ptr_set.cpp @@ -138,6 +138,15 @@ gb_inline bool ptr_set_exists(PtrSet *s, T ptr) { return index != MAP_SENTINEL; } +template +gb_inline isize ptr_entry_index(PtrSet *s, T ptr) { + isize index = ptr_set__find(s, ptr).entry_index; + if (index != MAP_SENTINEL) { + return index; + } + return -1; +} + // Returns true if it already exists template T ptr_set_add(PtrSet *s, T ptr) { -- cgit v1.2.3 From 42ab882db4a6d5765c68021ade010b468ff4531e Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 24 Jan 2022 15:56:26 +0000 Subject: Remove debug code --- src/check_expr.cpp | 1 - src/checker.cpp | 3 --- 2 files changed, 4 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 81f69055a..1742ef2d8 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -3419,7 +3419,6 @@ void convert_untyped_error(CheckerContext *c, Operand *operand, Type *target_typ if (operand->value.kind == ExactValue_String) { String key = operand->value.value_string; if (is_type_string(operand->type) && is_type_enum(target_type)) { - gb_printf_err("HERE!\n"); Type *et = base_type(target_type); check_did_you_mean_type(key, et->Enum.fields, "."); } diff --git a/src/checker.cpp b/src/checker.cpp index 55a3892e5..b81d9987b 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1618,9 +1618,6 @@ void add_type_info_type_internal(CheckerContext *c, Type *t) { // NOTE(bill): map entries grow linearly and in order ti_index = c->info->type_info_types.count; array_add(&c->info->type_info_types, t); - if (t->kind == Type_Named && t->Named.name == "A") { - gb_printf_err("HERE!\n"); - } } map_set(&c->checker->info.type_info_map, t, ti_index); -- cgit v1.2.3 From f6a087775e0a7baf97bce7b1ebb59b223b10d047 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 25 Jan 2022 12:39:06 +0000 Subject: Disable early return from `check_proc_info` --- src/checker.cpp | 13 +++++++------ src/llvm_backend_proc.cpp | 2 +- 2 files changed, 8 insertions(+), 7 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index b81d9987b..9be64e369 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -4855,12 +4855,13 @@ bool check_proc_info(Checker *c, ProcInfo *pi, UntypedExprInfoMap *untyped, Proc return false; } - if (pt->is_polymorphic && pt->is_poly_specialized) { - if ((e->flags & EntityFlag_Used) == 0) { - // NOTE(bill, 2019-08-31): It was never used, don't check - return false; - } - } + // NOTE(bill, 2022-01-25): Appears to be not needed any more + // if (pt->is_polymorphic && pt->is_poly_specialized) { + // if ((e->flags & EntityFlag_Used) == 0) { + // // NOTE(bill, 2019-08-31): It was never used, don't check + // return false; + // } + // } bool bounds_check = (pi->tags & ProcTag_bounds_check) != 0; bool no_bounds_check = (pi->tags & ProcTag_no_bounds_check) != 0; diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index b35c6c304..9f9fe7c7a 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -61,7 +61,7 @@ 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) { - GB_ASSERT(entity->flags & EntityFlag_ProcBodyChecked); + GB_ASSERT_MSG(entity->flags & EntityFlag_ProcBodyChecked, "%.*s :: %s", LIT(entity->token.string), type_to_string(entity->type)); } String link_name = {}; -- cgit v1.2.3 From a3e7b2baa1ede7ba328a9ec6b249051347ef4cae Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 25 Jan 2022 12:42:45 +0000 Subject: Revert change --- src/checker.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index 9be64e369..b81d9987b 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -4855,13 +4855,12 @@ bool check_proc_info(Checker *c, ProcInfo *pi, UntypedExprInfoMap *untyped, Proc return false; } - // NOTE(bill, 2022-01-25): Appears to be not needed any more - // if (pt->is_polymorphic && pt->is_poly_specialized) { - // if ((e->flags & EntityFlag_Used) == 0) { - // // NOTE(bill, 2019-08-31): It was never used, don't check - // return false; - // } - // } + if (pt->is_polymorphic && pt->is_poly_specialized) { + if ((e->flags & EntityFlag_Used) == 0) { + // NOTE(bill, 2019-08-31): It was never used, don't check + return false; + } + } bool bounds_check = (pi->tags & ProcTag_bounds_check) != 0; bool no_bounds_check = (pi->tags & ProcTag_no_bounds_check) != 0; -- cgit v1.2.3 From 070b4507686570335cb3624ef1ede6f442bd4866 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 26 Jan 2022 17:34:39 +0000 Subject: Add `ODIN_ERROR_POS_STYLE` constant and change `runtime.print_caller_location` based on that constant --- core/runtime/print.odin | 20 +++++++++++++++----- src/build_settings.cpp | 2 ++ src/checker.cpp | 10 ++++++++++ 3 files changed, 27 insertions(+), 5 deletions(-) (limited to 'src/checker.cpp') diff --git a/core/runtime/print.odin b/core/runtime/print.odin index 8a14eba08..8c0b65864 100644 --- a/core/runtime/print.odin +++ b/core/runtime/print.odin @@ -143,11 +143,21 @@ print_int :: proc "contextless" (x: int) { print_i64(i64(x)) } print_caller_location :: proc "contextless" (using loc: Source_Code_Location) { print_string(file_path) - print_byte('(') - print_u64(u64(line)) - print_byte(':') - print_u64(u64(column)) - print_byte(')') + when ODIN_ERROR_POS_STYLE == .Default { + print_byte('(') + print_u64(u64(line)) + print_byte(':') + print_u64(u64(column)) + print_byte(')') + } else when ODIN_ERROR_POS_STYLE == .Unix { + print_byte(':') + print_u64(u64(line)) + print_byte(':') + print_u64(u64(column)) + print_byte(':') + } else { + #panic("unhandled ODIN_ERROR_POS_STYLE") + } } print_typeid :: proc "contextless" (id: typeid) { if id == nil { diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 96339be29..610e4f847 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -168,6 +168,8 @@ enum TimingsExportFormat : i32 { enum ErrorPosStyle { ErrorPosStyle_Default, // path(line:column) msg ErrorPosStyle_Unix, // path:line:column: msg + + ErrorPosStyle_COUNT }; // This stores the information for the specify architecture of this build diff --git a/src/checker.cpp b/src/checker.cpp index b81d9987b..e0c756bb8 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -893,6 +893,16 @@ void init_universal(void) { add_global_enum_constant(fields, "ODIN_ENDIAN", target_endians[bc->metrics.arch]); } + { + GlobalEnumValue values[ErrorPosStyle_COUNT] = { + {"Default", ErrorPosStyle_Default}, + {"Unix", ErrorPosStyle_Unix}, + }; + + auto fields = add_global_enum_type(str_lit("Odin_Error_Pos_Style_Type"), values, gb_count_of(values)); + add_global_enum_constant(fields, "ODIN_ERROR_POS_STYLE", build_context.ODIN_ERROR_POS_STYLE); + } + add_global_bool_constant("ODIN_DEBUG", bc->ODIN_DEBUG); add_global_bool_constant("ODIN_DISABLE_ASSERT", bc->ODIN_DISABLE_ASSERT); -- cgit v1.2.3 From 24e7356825a473cba0a1e9962470be73d60ad248 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 27 Jan 2022 16:08:47 +0000 Subject: Add `#no_type_assert` and `#type_assert` to disable implicit type assertions with `x.(T)` --- src/check_expr.cpp | 8 +++++ src/check_stmt.cpp | 8 +++++ src/checker.cpp | 12 ++++++++ src/llvm_backend_expr.cpp | 72 +++++++++++++++++++++++++------------------- src/llvm_backend_stmt.cpp | 7 +++++ src/llvm_backend_utility.cpp | 41 ++++++++++++++++--------- src/parser.cpp | 36 ++++++++++++++++++++++ src/parser.hpp | 4 +++ 8 files changed, 142 insertions(+), 46 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 276e9d0bb..fb5a90f5a 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -6883,6 +6883,14 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type out &= ~StateFlag_no_bounds_check; } + if (in & StateFlag_no_type_assert) { + out |= StateFlag_no_type_assert; + out &= ~StateFlag_type_assert; + } else if (in & StateFlag_type_assert) { + out |= StateFlag_type_assert; + out &= ~StateFlag_no_type_assert; + } + c->state_flags = out; } diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index 94b7561c7..f9e55ab37 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -490,6 +490,14 @@ void check_stmt(CheckerContext *ctx, Ast *node, u32 flags) { out &= ~StateFlag_no_bounds_check; } + if (in & StateFlag_no_type_assert) { + out |= StateFlag_no_type_assert; + out &= ~StateFlag_type_assert; + } else if (in & StateFlag_type_assert) { + out |= StateFlag_type_assert; + out &= ~StateFlag_no_type_assert; + } + ctx->state_flags = out; } diff --git a/src/checker.cpp b/src/checker.cpp index e0c756bb8..038709056 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -4875,6 +4875,9 @@ bool check_proc_info(Checker *c, ProcInfo *pi, UntypedExprInfoMap *untyped, Proc bool bounds_check = (pi->tags & ProcTag_bounds_check) != 0; bool no_bounds_check = (pi->tags & ProcTag_no_bounds_check) != 0; + bool type_assert = (pi->tags & ProcTag_type_assert) != 0; + bool no_type_assert = (pi->tags & ProcTag_no_type_assert) != 0; + if (bounds_check) { ctx.state_flags |= StateFlag_bounds_check; ctx.state_flags &= ~StateFlag_no_bounds_check; @@ -4882,6 +4885,15 @@ bool check_proc_info(Checker *c, ProcInfo *pi, UntypedExprInfoMap *untyped, Proc ctx.state_flags |= StateFlag_no_bounds_check; ctx.state_flags &= ~StateFlag_bounds_check; } + + if (type_assert) { + ctx.state_flags |= StateFlag_type_assert; + ctx.state_flags &= ~StateFlag_no_type_assert; + } else if (no_type_assert) { + ctx.state_flags |= StateFlag_no_type_assert; + ctx.state_flags &= ~StateFlag_type_assert; + } + if (pi->body != nullptr && e != nullptr) { GB_ASSERT((e->flags & EntityFlag_ProcBodyChecked) == 0); } diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp index 9b2e26434..ea031ee56 100644 --- a/src/llvm_backend_expr.cpp +++ b/src/llvm_backend_expr.cpp @@ -2768,27 +2768,29 @@ lbValue lb_build_unary_and(lbProcedure *p, Ast *expr) { Type *src_type = type_deref(v.type); Type *dst_type = type; - lbValue src_tag = {}; - lbValue dst_tag = {}; - if (is_type_union_maybe_pointer(src_type)) { - src_tag = lb_emit_comp_against_nil(p, Token_NotEq, v); - dst_tag = lb_const_bool(p->module, t_bool, true); - } else { - src_tag = lb_emit_load(p, lb_emit_union_tag_ptr(p, v)); - dst_tag = lb_const_union_tag(p->module, src_type, dst_type); - } - lbValue ok = lb_emit_comp(p, Token_CmpEq, src_tag, dst_tag); - auto args = array_make(permanent_allocator(), 6); - args[0] = ok; + if ((p->state_flags & StateFlag_no_type_assert) == 0) { + lbValue src_tag = {}; + lbValue dst_tag = {}; + if (is_type_union_maybe_pointer(src_type)) { + src_tag = lb_emit_comp_against_nil(p, Token_NotEq, v); + dst_tag = lb_const_bool(p->module, t_bool, true); + } else { + src_tag = lb_emit_load(p, lb_emit_union_tag_ptr(p, v)); + dst_tag = lb_const_union_tag(p->module, src_type, dst_type); + } + lbValue ok = lb_emit_comp(p, Token_CmpEq, src_tag, dst_tag); + auto args = array_make(permanent_allocator(), 6); + args[0] = ok; - args[1] = lb_find_or_add_entity_string(p->module, get_file_path_string(pos.file_id)); - args[2] = lb_const_int(p->module, t_i32, pos.line); - args[3] = lb_const_int(p->module, t_i32, pos.column); + args[1] = lb_find_or_add_entity_string(p->module, get_file_path_string(pos.file_id)); + args[2] = lb_const_int(p->module, t_i32, pos.line); + args[3] = lb_const_int(p->module, t_i32, pos.column); - args[4] = lb_typeid(p->module, src_type); - args[5] = lb_typeid(p->module, dst_type); - lb_emit_runtime_call(p, "type_assertion_check", args); + args[4] = lb_typeid(p->module, src_type); + args[5] = lb_typeid(p->module, dst_type); + lb_emit_runtime_call(p, "type_assertion_check", args); + } lbValue data_ptr = v; return lb_emit_conv(p, data_ptr, tv.type); @@ -2797,23 +2799,23 @@ lbValue lb_build_unary_and(lbProcedure *p, Ast *expr) { if (is_type_pointer(v.type)) { v = lb_emit_load(p, v); } - lbValue data_ptr = lb_emit_struct_ev(p, v, 0); - lbValue any_id = lb_emit_struct_ev(p, v, 1); - lbValue id = lb_typeid(p->module, type); + if ((p->state_flags & StateFlag_no_type_assert) == 0) { + lbValue any_id = lb_emit_struct_ev(p, v, 1); + lbValue id = lb_typeid(p->module, type); + lbValue ok = lb_emit_comp(p, Token_CmpEq, any_id, id); + auto args = array_make(permanent_allocator(), 6); + args[0] = ok; - lbValue ok = lb_emit_comp(p, Token_CmpEq, any_id, id); - auto args = array_make(permanent_allocator(), 6); - args[0] = ok; - - args[1] = lb_find_or_add_entity_string(p->module, get_file_path_string(pos.file_id)); - args[2] = lb_const_int(p->module, t_i32, pos.line); - args[3] = lb_const_int(p->module, t_i32, pos.column); + args[1] = lb_find_or_add_entity_string(p->module, get_file_path_string(pos.file_id)); + args[2] = lb_const_int(p->module, t_i32, pos.line); + args[3] = lb_const_int(p->module, t_i32, pos.column); - args[4] = any_id; - args[5] = id; - lb_emit_runtime_call(p, "type_assertion_check", args); + args[4] = any_id; + args[5] = id; + lb_emit_runtime_call(p, "type_assertion_check", args); + } return lb_emit_conv(p, data_ptr, tv.type); } else { @@ -2843,6 +2845,14 @@ lbValue lb_build_expr(lbProcedure *p, Ast *expr) { out &= ~StateFlag_bounds_check; } + if (in & StateFlag_type_assert) { + out |= StateFlag_type_assert; + out &= ~StateFlag_no_type_assert; + } else if (in & StateFlag_no_type_assert) { + out |= StateFlag_no_type_assert; + out &= ~StateFlag_type_assert; + } + p->state_flags = out; } diff --git a/src/llvm_backend_stmt.cpp b/src/llvm_backend_stmt.cpp index 3375ceda9..916c0433e 100644 --- a/src/llvm_backend_stmt.cpp +++ b/src/llvm_backend_stmt.cpp @@ -1991,6 +1991,13 @@ void lb_build_stmt(lbProcedure *p, Ast *node) { out |= StateFlag_no_bounds_check; out &= ~StateFlag_bounds_check; } + if (in & StateFlag_no_type_assert) { + out |= StateFlag_no_type_assert; + out &= ~StateFlag_type_assert; + } else if (in & StateFlag_type_assert) { + out |= StateFlag_type_assert; + out &= ~StateFlag_no_type_assert; + } p->state_flags = out; } diff --git a/src/llvm_backend_utility.cpp b/src/llvm_backend_utility.cpp index 5b1b11b44..7e2bd7daa 100644 --- a/src/llvm_backend_utility.cpp +++ b/src/llvm_backend_utility.cpp @@ -626,6 +626,12 @@ lbValue lb_emit_union_cast(lbProcedure *p, lbValue value, Type *type, TokenPos p lbValue value_ = lb_address_from_load_or_generate_local(p, value); + if ((p->state_flags & StateFlag_no_type_assert) != 0 && !is_tuple) { + // just do a bit cast of the data at the front + lbValue ptr = lb_emit_conv(p, value_, alloc_type_pointer(type)); + return lb_emit_load(p, ptr); + } + lbValue tag = {}; lbValue dst_tag = {}; lbValue cond = {}; @@ -666,23 +672,22 @@ lbValue lb_emit_union_cast(lbProcedure *p, lbValue value, Type *type, TokenPos p lb_start_block(p, end_block); if (!is_tuple) { - { - // NOTE(bill): Panic on invalid conversion - Type *dst_type = tuple->Tuple.variables[0]->type; + GB_ASSERT((p->state_flags & StateFlag_no_type_assert) == 0); + // NOTE(bill): Panic on invalid conversion + Type *dst_type = tuple->Tuple.variables[0]->type; - lbValue ok = lb_emit_load(p, lb_emit_struct_ep(p, v.addr, 1)); - auto args = array_make(permanent_allocator(), 7); - args[0] = ok; + lbValue ok = lb_emit_load(p, lb_emit_struct_ep(p, v.addr, 1)); + auto args = array_make(permanent_allocator(), 7); + args[0] = ok; - args[1] = lb_const_string(m, get_file_path_string(pos.file_id)); - args[2] = lb_const_int(m, t_i32, pos.line); - args[3] = lb_const_int(m, t_i32, pos.column); + args[1] = lb_const_string(m, get_file_path_string(pos.file_id)); + args[2] = lb_const_int(m, t_i32, pos.line); + args[3] = lb_const_int(m, t_i32, pos.column); - args[4] = lb_typeid(m, src_type); - args[5] = lb_typeid(m, dst_type); - args[6] = lb_emit_conv(p, value_, t_rawptr); - lb_emit_runtime_call(p, "type_assertion_check2", args); - } + args[4] = lb_typeid(m, src_type); + args[5] = lb_typeid(m, dst_type); + args[6] = lb_emit_conv(p, value_, t_rawptr); + lb_emit_runtime_call(p, "type_assertion_check2", args); return lb_emit_load(p, lb_emit_struct_ep(p, v.addr, 0)); } @@ -706,6 +711,13 @@ lbAddr lb_emit_any_cast_addr(lbProcedure *p, lbValue value, Type *type, TokenPos } Type *dst_type = tuple->Tuple.variables[0]->type; + if ((p->state_flags & StateFlag_no_type_assert) != 0 && !is_tuple) { + // just do a bit cast of the data at the front + lbValue ptr = lb_emit_struct_ev(p, value, 0); + ptr = lb_emit_conv(p, ptr, alloc_type_pointer(type)); + return lb_addr(ptr); + } + lbAddr v = lb_add_local_generated(p, tuple, true); lbValue dst_typeid = lb_typeid(m, dst_type); @@ -731,7 +743,6 @@ lbAddr lb_emit_any_cast_addr(lbProcedure *p, lbValue value, Type *type, TokenPos if (!is_tuple) { // NOTE(bill): Panic on invalid conversion - lbValue ok = lb_emit_load(p, lb_emit_struct_ep(p, v.addr, 1)); auto args = array_make(permanent_allocator(), 7); args[0] = ok; diff --git a/src/parser.cpp b/src/parser.cpp index 108411cd0..9cc9adfc9 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -1843,6 +1843,8 @@ void parse_proc_tags(AstFile *f, u64 *tags) { ELSE_IF_ADD_TAG(require_results) ELSE_IF_ADD_TAG(bounds_check) ELSE_IF_ADD_TAG(no_bounds_check) + ELSE_IF_ADD_TAG(type_assert) + ELSE_IF_ADD_TAG(no_type_assert) else { syntax_error(tag_expr, "Unknown procedure type tag #%.*s", LIT(tag_name)); } @@ -1853,6 +1855,10 @@ void parse_proc_tags(AstFile *f, u64 *tags) { if ((*tags & ProcTag_bounds_check) && (*tags & ProcTag_no_bounds_check)) { syntax_error(f->curr_token, "You cannot apply both #bounds_check and #no_bounds_check to a procedure"); } + + if ((*tags & ProcTag_type_assert) && (*tags & ProcTag_no_type_assert)) { + syntax_error(f->curr_token, "You cannot apply both #type_assert and #no_type_assert to a procedure"); + } } @@ -2000,11 +2006,23 @@ Ast *parse_check_directive_for_statement(Ast *s, Token const &tag_token, u16 sta syntax_error(tag_token, "#bounds_check and #no_bounds_check cannot be applied together"); } break; + case StateFlag_type_assert: + if ((s->state_flags & StateFlag_no_type_assert) != 0) { + syntax_error(tag_token, "#type_assert and #no_type_assert cannot be applied together"); + } + break; + case StateFlag_no_type_assert: + if ((s->state_flags & StateFlag_type_assert) != 0) { + syntax_error(tag_token, "#type_assert and #no_type_assert cannot be applied together"); + } + break; } switch (state_flag) { case StateFlag_bounds_check: case StateFlag_no_bounds_check: + case StateFlag_type_assert: + case StateFlag_no_type_assert: switch (s->kind) { case Ast_BlockStmt: case Ast_IfStmt: @@ -2128,6 +2146,12 @@ Ast *parse_operand(AstFile *f, bool lhs) { } else if (name.string == "no_bounds_check") { Ast *operand = parse_expr(f, lhs); return parse_check_directive_for_statement(operand, name, StateFlag_no_bounds_check); + } else if (name.string == "type_assert") { + Ast *operand = parse_expr(f, lhs); + return parse_check_directive_for_statement(operand, name, StateFlag_type_assert); + } else if (name.string == "no_type_assert") { + Ast *operand = parse_expr(f, lhs); + return parse_check_directive_for_statement(operand, name, StateFlag_no_type_assert); } else if (name.string == "relative") { Ast *tag = ast_basic_directive(f, token, name); tag = parse_call_expr(f, tag); @@ -2224,6 +2248,12 @@ Ast *parse_operand(AstFile *f, bool lhs) { if (tags & ProcTag_bounds_check) { body->state_flags |= StateFlag_bounds_check; } + if (tags & ProcTag_no_type_assert) { + body->state_flags |= StateFlag_no_type_assert; + } + if (tags & ProcTag_type_assert) { + body->state_flags |= StateFlag_type_assert; + } return ast_proc_lit(f, type, body, tags, where_token, where_clauses); } else if (allow_token(f, Token_do)) { @@ -4611,6 +4641,12 @@ Ast *parse_stmt(AstFile *f) { } else if (tag == "no_bounds_check") { s = parse_stmt(f); return parse_check_directive_for_statement(s, name, StateFlag_no_bounds_check); + } else if (tag == "type_assert") { + s = parse_stmt(f); + return parse_check_directive_for_statement(s, name, StateFlag_type_assert); + } else if (tag == "no_type_assert") { + s = parse_stmt(f); + return parse_check_directive_for_statement(s, name, StateFlag_no_type_assert); } else if (tag == "partial") { s = parse_stmt(f); switch (s->kind) { diff --git a/src/parser.hpp b/src/parser.hpp index b005a4465..656f709e8 100644 --- a/src/parser.hpp +++ b/src/parser.hpp @@ -226,6 +226,8 @@ enum ProcInlining { enum ProcTag { ProcTag_bounds_check = 1<<0, ProcTag_no_bounds_check = 1<<1, + ProcTag_type_assert = 1<<2, + ProcTag_no_type_assert = 1<<3, ProcTag_require_results = 1<<4, ProcTag_optional_ok = 1<<5, @@ -258,6 +260,8 @@ ProcCallingConvention default_calling_convention(void) { enum StateFlag : u8 { StateFlag_bounds_check = 1<<0, StateFlag_no_bounds_check = 1<<1, + StateFlag_type_assert = 1<<2, + StateFlag_no_type_assert = 1<<3, StateFlag_BeenHandled = 1<<7, }; -- cgit v1.2.3 From 67ba05cb7cfee60daaf257230ddbc4f1e0a9f8ac Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 31 Jan 2022 19:33:02 +0000 Subject: Correct false positive check in `check_unique_package_names` --- src/checker.cpp | 10 ++++++++-- src/parser.cpp | 5 +++++ src/parser_pos.cpp | 6 ++++++ 3 files changed, 19 insertions(+), 2 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index 038709056..d9a1af0d1 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -5307,12 +5307,18 @@ void check_unique_package_names(Checker *c) { string_map_set(&pkgs, key, pkg); continue; } + auto *this = pkg->files[0]->pkg_decl; + auto *other = (*found)->files[0]->pkg_decl; + if (this == other) { + // NOTE(bill): A false positive was found, ignore it + continue; + } - error(pkg->files[0]->pkg_decl, "Duplicate declaration of 'package %.*s'", LIT(name)); + error(this, "Duplicate declaration of 'package %.*s'", LIT(name)); error_line("\tA package name must be unique\n" "\tThere is no relation between a package name and the directory that contains it, so they can be completely different\n" "\tA package name is required for link name prefixing to have a consistent ABI\n"); - error((*found)->files[0]->pkg_decl, "found at previous location"); + error(other, "found at previous location"); } } diff --git a/src/parser.cpp b/src/parser.cpp index 9cc9adfc9..7a858e520 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -183,6 +183,11 @@ Ast *clone_ast(Ast *node) { n->FieldValue.value = clone_ast(n->FieldValue.value); break; + case Ast_EnumFieldValue: + n->EnumFieldValue.name = clone_ast(n->EnumFieldValue.name); + n->EnumFieldValue.value = clone_ast(n->EnumFieldValue.value); + break; + case Ast_TernaryIfExpr: n->TernaryIfExpr.x = clone_ast(n->TernaryIfExpr.x); n->TernaryIfExpr.cond = clone_ast(n->TernaryIfExpr.cond); diff --git a/src/parser_pos.cpp b/src/parser_pos.cpp index 6ef0db215..54c3ec1f1 100644 --- a/src/parser_pos.cpp +++ b/src/parser_pos.cpp @@ -39,6 +39,7 @@ Token ast_token(Ast *node) { case Ast_SliceExpr: return node->SliceExpr.open; case Ast_Ellipsis: return node->Ellipsis.token; case Ast_FieldValue: return node->FieldValue.eq; + case Ast_EnumFieldValue: return ast_token(node->EnumFieldValue.name); case Ast_DerefExpr: return node->DerefExpr.op; case Ast_TernaryIfExpr: return ast_token(node->TernaryIfExpr.x); case Ast_TernaryWhenExpr: return ast_token(node->TernaryWhenExpr.x); @@ -178,6 +179,11 @@ Token ast_end_token(Ast *node) { } return node->Ellipsis.token; case Ast_FieldValue: return ast_end_token(node->FieldValue.value); + case Ast_EnumFieldValue: + if (node->EnumFieldValue.value) { + return ast_end_token(node->EnumFieldValue.value); + } + return ast_end_token(node->EnumFieldValue.name); case Ast_DerefExpr: return node->DerefExpr.op; case Ast_TernaryIfExpr: return ast_end_token(node->TernaryIfExpr.y); case Ast_TernaryWhenExpr: return ast_end_token(node->TernaryWhenExpr.y); -- cgit v1.2.3 From 85706d559d06998895b27710f5e4f4643443b032 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 31 Jan 2022 20:19:46 +0000 Subject: Fix typo --- src/checker.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index d9a1af0d1..d50d4d176 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -5307,18 +5307,18 @@ void check_unique_package_names(Checker *c) { string_map_set(&pkgs, key, pkg); continue; } - auto *this = pkg->files[0]->pkg_decl; - auto *other = (*found)->files[0]->pkg_decl; - if (this == other) { + auto *curr = pkg->files[0]->pkg_decl; + auto *prev = (*found)->files[0]->pkg_decl; + if (curr == prev) { // NOTE(bill): A false positive was found, ignore it continue; } - error(this, "Duplicate declaration of 'package %.*s'", LIT(name)); + error(curr, "Duplicate declaration of 'package %.*s'", LIT(name)); error_line("\tA package name must be unique\n" "\tThere is no relation between a package name and the directory that contains it, so they can be completely different\n" "\tA package name is required for link name prefixing to have a consistent ABI\n"); - error(other, "found at previous location"); + error(prev, "found at previous location"); } } -- cgit v1.2.3 From 78815778ee399b4df1c5f7c44522c792b9dc3e23 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 2 Feb 2022 15:28:49 +0000 Subject: Add `//+private file` to complement `//+private` (`//+private package`) --- src/checker.cpp | 9 ++++++--- src/entity.cpp | 2 +- src/parser.cpp | 12 ++++++++++-- src/parser.hpp | 8 +++++--- src/string.cpp | 12 ++++++++++-- 5 files changed, 32 insertions(+), 11 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index d50d4d176..4dcb5120f 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -3467,9 +3467,12 @@ void check_collect_value_decl(CheckerContext *c, Ast *decl) { if (entity_visibility_kind == EntityVisiblity_Public && (c->scope->flags&ScopeFlag_File) && - c->scope->file && - (c->scope->file->flags & AstFile_IsPrivate)) { - entity_visibility_kind = EntityVisiblity_PrivateToPackage; + c->scope->file) { + if (c->scope->file->flags & AstFile_IsPrivatePkg) { + entity_visibility_kind = EntityVisiblity_PrivateToPackage; + } else if (c->scope->file->flags & AstFile_IsPrivateFile) { + entity_visibility_kind = EntityVisiblity_PrivateToFile; + } } if (entity_visibility_kind != EntityVisiblity_Public && !(c->scope->flags&ScopeFlag_File)) { diff --git a/src/entity.cpp b/src/entity.cpp index a0438a9f4..8327a517e 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -245,7 +245,7 @@ bool is_entity_exported(Entity *e, bool allow_builtin = false) { if (e->flags & EntityFlag_NotExported) { return false; } - if (e->file != nullptr && (e->file->flags & AstFile_IsPrivate) != 0) { + if (e->file != nullptr && (e->file->flags & (AstFile_IsPrivatePkg|AstFile_IsPrivateFile)) != 0) { return false; } diff --git a/src/parser.cpp b/src/parser.cpp index 7a858e520..bf8c909c2 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -5535,8 +5535,16 @@ bool parse_file(Parser *p, AstFile *f) { if (!parse_build_tag(tok, lc)) { return false; } - } else if (lc == "+private") { - f->flags |= AstFile_IsPrivate; + } else if (string_starts_with(lc, str_lit("+private"))) { + f->flags |= AstFile_IsPrivatePkg; + String command = string_trim_starts_with(lc, str_lit("+private ")); + if (lc == "+private") { + f->flags |= AstFile_IsPrivatePkg; + } else if (command == "package") { + f->flags |= AstFile_IsPrivatePkg; + } else if (command == "file") { + f->flags |= AstFile_IsPrivateFile; + } } else if (lc == "+lazy") { if (build_context.ignore_lazy) { // Ignore diff --git a/src/parser.hpp b/src/parser.hpp index 656f709e8..0712e83cb 100644 --- a/src/parser.hpp +++ b/src/parser.hpp @@ -78,9 +78,11 @@ struct ImportedFile { }; enum AstFileFlag : u32 { - AstFile_IsPrivate = 1<<0, - AstFile_IsTest = 1<<1, - AstFile_IsLazy = 1<<2, + AstFile_IsPrivatePkg = 1<<0, + AstFile_IsPrivateFile = 1<<1, + + AstFile_IsTest = 1<<3, + AstFile_IsLazy = 1<<4, }; enum AstDelayQueueKind { diff --git a/src/string.cpp b/src/string.cpp index 800378689..eb6058f78 100644 --- a/src/string.cpp +++ b/src/string.cpp @@ -195,8 +195,6 @@ template bool operator > (String const &a, char const (&b)[N]) { retu template bool operator <= (String const &a, char const (&b)[N]) { return str_le(a, make_string(cast(u8 *)b, N-1)); } template 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) { if (prefix.len > s.len) { return false; @@ -230,6 +228,16 @@ gb_inline bool string_ends_with(String const &s, u8 suffix) { return s[s.len-1] == suffix; } + + +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); + } + return s; +} + + gb_inline isize string_extension_position(String const &str) { isize dot_pos = -1; isize i = str.len; -- cgit v1.2.3 From 35c90fe12413335962cad02d77a4894079b00a5d Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 3 Feb 2022 13:34:31 +0000 Subject: Fix type alias declaration evaluation problem (#854 #1439) --- src/check_decl.cpp | 39 +++++++++++++++++- src/check_expr.cpp | 113 ++++++++++++++++++++++++++++++++++++++++++++++------- src/checker.cpp | 3 -- 3 files changed, 137 insertions(+), 18 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/check_decl.cpp b/src/check_decl.cpp index f9bc17ba4..193c28aea 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -385,7 +385,44 @@ void check_const_decl(CheckerContext *ctx, Entity *e, Ast *type_expr, Ast *init, Operand operand = {}; if (init != nullptr) { - Entity *entity = nullptr; + Entity *entity = check_entity_from_ident_or_selector(ctx, init); + if (entity != nullptr && entity->kind == Entity_TypeName) { + // NOTE(bill, 2022-02-03): This is used to solve the problem caused by type aliases + // being "confused" as constants + // + // A :: B + // C :: proc "c" (^A) + // B :: struct {x: C} + // + // A gets evaluated first, and then checks B. + // B then checks C. + // C then tries to check A which is unresolved but thought to be a constant. + // Therefore within C's check, A errs as "not a type". + // + // This is because a const declaration may or may not be a type and this cannot + // be determined from a syntactical standpoint. + // This check allows the compiler to override the entity to be checked as a type. + // + // There is no problem if B is prefixed with the `#type` helper enforcing at + // both a syntax and semantic level that B must be a type. + // + // A :: #type B + // + // This approach is not fool proof and can fail in case such as: + // + // X :: type_of(x) + // X :: Foo(int).Type + // + // Since even these kind of declarations may cause weird checking cycles. + // For the time being, these are going to be treated as an unfortunate error + // until there is a proper delaying system to try declaration again if they + // have failed. + + e->kind = Entity_TypeName; + check_type_decl(ctx, e, init, named_type); + return; + } + entity = nullptr; if (init->kind == Ast_Ident) { entity = check_ident(ctx, &operand, init, nullptr, e->type, true); } else if (init->kind == Ast_SelectorExpr) { diff --git a/src/check_expr.cpp b/src/check_expr.cpp index fb5a90f5a..88296611b 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -1286,7 +1286,6 @@ bool check_cycle(CheckerContext *c, Entity *curr, bool report) { return false; } - Entity *check_ident(CheckerContext *c, Operand *o, Ast *n, Type *named_type, Type *type_hint, bool allow_import_name) { GB_ASSERT(n->kind == Ast_Ident); o->mode = Addressing_Invalid; @@ -1422,8 +1421,12 @@ Entity *check_ident(CheckerContext *c, Operand *o, Ast *n, Type *named_type, Typ case Entity_TypeName: o->mode = Addressing_Type; if (check_cycle(c, e, true)) { - type = t_invalid; + o->type = t_invalid; + } + if (o->type != nullptr && type->kind == Type_Named && o->type->Named.type_name->TypeName.is_type_alias) { + o->type = base_type(o->type); } + break; case Entity_ImportName: @@ -4064,6 +4067,98 @@ Type *determine_swizzle_array_type(Type *original_type, Type *type_hint, isize n } +bool is_entity_declared_for_selector(Entity *entity, Scope *import_scope, bool *allow_builtin) { + bool is_declared = entity != nullptr; + if (is_declared) { + if (entity->kind == Entity_Builtin) { + // NOTE(bill): Builtin's are in the universal scope which is part of every scopes hierarchy + // This means that we should just ignore the found result through it + *allow_builtin = entity->scope == import_scope || entity->scope != builtin_pkg->scope; + } else if ((entity->scope->flags&ScopeFlag_Global) == ScopeFlag_Global && (import_scope->flags&ScopeFlag_Global) == 0) { + is_declared = false; + } + } + return is_declared; +} + +// NOTE(bill, 2022-02-03): see `check_const_decl` for why it exists reasoning +Entity *check_entity_from_ident_or_selector(CheckerContext *c, Ast *node) { + if (node->kind == Ast_Ident) { + String name = node->Ident.token.string; + return scope_lookup(c->scope, name); + } else if (node->kind == Ast_SelectorExpr) { + ast_node(se, SelectorExpr, node); + if (!c->allow_arrow_right_selector_expr && se->token.kind == Token_ArrowRight) { + return nullptr; + } + + Ast *op_expr = se->expr; + Ast *selector = unparen_expr(se->selector); + if (selector == nullptr) { + return nullptr; + } + if (selector->kind != Ast_Ident) { + return nullptr; + } + + Entity *entity = nullptr; + Entity *expr_entity = nullptr; + bool check_op_expr = true; + + if (op_expr->kind == Ast_Ident) { + String op_name = op_expr->Ident.token.string; + Entity *e = scope_lookup(c->scope, op_name); + add_entity_use(c, op_expr, e); + expr_entity = e; + + if (e != nullptr && e->kind == Entity_ImportName && selector->kind == Ast_Ident) { + // IMPORTANT NOTE(bill): This is very sloppy code but it's also very fragile + // It pretty much needs to be in this order and this way + // If you can clean this up, please do but be really careful + String import_name = op_name; + Scope *import_scope = e->ImportName.scope; + String entity_name = selector->Ident.token.string; + + check_op_expr = false; + entity = scope_lookup_current(import_scope, entity_name); + bool allow_builtin = false; + if (!is_entity_declared_for_selector(entity, import_scope, &allow_builtin)) { + return nullptr; + } + + check_entity_decl(c, entity, nullptr, nullptr); + if (entity->kind == Entity_ProcGroup) { + return entity; + } + GB_ASSERT_MSG(entity->type != nullptr, "%.*s (%.*s)", LIT(entity->token.string), LIT(entity_strings[entity->kind])); + } + } + + Operand operand = {}; + if (check_op_expr) { + check_expr_base(c, &operand, op_expr, nullptr); + if (operand.mode == Addressing_Invalid) { + return nullptr; + } + } + + if (entity == nullptr && selector->kind == Ast_Ident) { + String field_name = selector->Ident.token.string; + if (is_type_dynamic_array(type_deref(operand.type))) { + init_mem_allocator(c->checker); + } + auto sel = lookup_field(operand.type, field_name, operand.mode == Addressing_Type); + entity = sel.entity; + } + + if (entity != nullptr) { + return entity; + } + } + return nullptr; +} + + Entity *check_selector(CheckerContext *c, Operand *operand, Ast *node, Type *type_hint) { ast_node(se, SelectorExpr, node); @@ -4112,18 +4207,8 @@ Entity *check_selector(CheckerContext *c, Operand *operand, Ast *node, Type *typ check_op_expr = false; entity = scope_lookup_current(import_scope, entity_name); - bool is_declared = entity != nullptr; bool allow_builtin = false; - if (is_declared) { - if (entity->kind == Entity_Builtin) { - // NOTE(bill): Builtin's are in the universal scope which is part of every scopes hierarchy - // This means that we should just ignore the found result through it - allow_builtin = entity->scope == import_scope || entity->scope != builtin_pkg->scope; - } else if ((entity->scope->flags&ScopeFlag_Global) == ScopeFlag_Global && (import_scope->flags&ScopeFlag_Global) == 0) { - is_declared = false; - } - } - if (!is_declared) { + if (!is_entity_declared_for_selector(entity, import_scope, &allow_builtin)) { error(op_expr, "'%.*s' is not declared by '%.*s'", LIT(entity_name), LIT(import_name)); operand->mode = Addressing_Invalid; operand->expr = node; @@ -4213,7 +4298,7 @@ Entity *check_selector(CheckerContext *c, Operand *operand, Ast *node, Type *typ } } - if (entity == nullptr && selector->kind == Ast_Ident && is_type_array(type_deref(operand->type))) { + if (entity == nullptr && selector->kind == Ast_Ident && is_type_array(type_deref(operand->type))) { // TODO(bill): Simd_Vector swizzling String field_name = selector->Ident.token.string; diff --git a/src/checker.cpp b/src/checker.cpp index 4dcb5120f..c4423b2bc 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -3563,9 +3563,6 @@ void check_collect_value_decl(CheckerContext *c, Ast *decl) { if (is_ast_type(init)) { e = alloc_entity_type_name(d->scope, token, nullptr); - // if (vd->type != nullptr) { - // error(name, "A type declaration cannot have an type parameter"); - // } } else if (init->kind == Ast_ProcLit) { if (c->scope->flags&ScopeFlag_Type) { error(name, "Procedure declarations are not allowed within a struct"); -- cgit v1.2.3 From 3a81f2ab898d537bba51b9ea81e047652112574e Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 4 Feb 2022 22:40:15 +0000 Subject: Correct the type aliasing problem, caused by aliases (of aliases)+ --- src/check_decl.cpp | 1 + src/check_expr.cpp | 5 ++++- src/checker.cpp | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 70 insertions(+), 2 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 193c28aea..2454feb33 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -387,6 +387,7 @@ void check_const_decl(CheckerContext *ctx, Entity *e, Ast *type_expr, Ast *init, if (init != nullptr) { Entity *entity = check_entity_from_ident_or_selector(ctx, init); if (entity != nullptr && entity->kind == Entity_TypeName) { + // @TypeAliasingProblem // NOTE(bill, 2022-02-03): This is used to solve the problem caused by type aliases // being "confused" as constants // diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 88296611b..e1c9bde84 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -4088,7 +4088,7 @@ Entity *check_entity_from_ident_or_selector(CheckerContext *c, Ast *node) { return scope_lookup(c->scope, name); } else if (node->kind == Ast_SelectorExpr) { ast_node(se, SelectorExpr, node); - if (!c->allow_arrow_right_selector_expr && se->token.kind == Token_ArrowRight) { + if (se->token.kind == Token_ArrowRight) { return nullptr; } @@ -4108,6 +4108,9 @@ Entity *check_entity_from_ident_or_selector(CheckerContext *c, Ast *node) { if (op_expr->kind == Ast_Ident) { String op_name = op_expr->Ident.token.string; Entity *e = scope_lookup(c->scope, op_name); + if (e == nullptr) { + return nullptr; + } add_entity_use(c, op_expr, e); expr_entity = e; diff --git a/src/checker.cpp b/src/checker.cpp index c4423b2bc..c90f357dd 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -3665,6 +3665,59 @@ void check_add_foreign_block_decl(CheckerContext *ctx, Ast *decl) { check_collect_entities(&c, block->stmts); } +bool correct_single_type_alias(CheckerContext *c, Entity *e) { + if (e->kind == Entity_Constant) { + DeclInfo *d = e->decl_info; + if (d != nullptr && d->init_expr != nullptr) { + Ast *init = d->init_expr; + Entity *alias_of = check_entity_from_ident_or_selector(c, init); + if (alias_of != nullptr && alias_of->kind == Entity_TypeName) { + e->kind = Entity_TypeName; + return true; + } + } + } + return false; +} + +bool correct_type_alias_in_scope_backwards(CheckerContext *c, Scope *s) { + isize n = s->elements.entries.count; + bool correction = false; + for (isize i = n-1; i >= 0; i--) { + correction |= correct_single_type_alias(c, s->elements.entries[i].value); + } + return correction; +} +bool correct_type_alias_in_scope_forwards(CheckerContext *c, Scope *s) { + isize n = s->elements.entries.count; + bool correction = false; + for (isize i = 0; i < n; i++) { + correction |= correct_single_type_alias(c, s->elements.entries[i].value); + } + return correction; +} + + +void correct_type_aliases_in_scope(CheckerContext *c, Scope *s) { + // NOTE(bill, 2022-02-04): This is used to solve the problem caused by type aliases + // of type aliases being "confused" as constants + // + // A :: C + // B :: A + // C :: struct {b: ^B} + // + // See @TypeAliasingProblem for more information + for (;;) { + bool corrections = false; + corrections |= correct_type_alias_in_scope_backwards(c, s); + corrections |= correct_type_alias_in_scope_forwards(c, s); + if (!corrections) { + return; + } + } +} + + // NOTE(bill): If file_scopes == nullptr, this will act like a local scope void check_collect_entities(CheckerContext *c, Slice const &nodes) { AstFile *curr_file = nullptr; @@ -3736,6 +3789,7 @@ void check_collect_entities(CheckerContext *c, Slice const &nodes) { } } + // correct_type_aliases(c); // NOTE(bill): 'when' stmts need to be handled after the other as the condition may refer to something // declared after this stmt in source @@ -4381,10 +4435,11 @@ bool collect_file_decls(CheckerContext *ctx, Slice const &decls) { for_array(i, decls) { if (collect_file_decl(ctx, decls[i])) { + correct_type_aliases_in_scope(ctx, ctx->scope); return true; } } - + correct_type_aliases_in_scope(ctx, ctx->scope); return false; } @@ -4654,6 +4709,15 @@ void check_import_entities(Checker *c) { } add_untyped_expressions(ctx.info, &untyped); } + + for_array(i, pkg->files) { + AstFile *f = pkg->files[i]; + reset_checker_context(&ctx, f, &untyped); + ctx.collect_delayed_decls = false; + + correct_type_aliases_in_scope(&ctx, pkg->scope); + } + for_array(i, pkg->files) { AstFile *f = pkg->files[i]; reset_checker_context(&ctx, f, &untyped); -- cgit v1.2.3 From d5384c5aa4d823fbd527fb82e9eb5559b4266dfd Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 4 Feb 2022 22:45:13 +0000 Subject: Only check idents in the alias (of alias)+ problem --- src/check_decl.cpp | 2 +- src/check_expr.cpp | 4 ++-- src/checker.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 2454feb33..63fc777c0 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -385,7 +385,7 @@ void check_const_decl(CheckerContext *ctx, Entity *e, Ast *type_expr, Ast *init, Operand operand = {}; if (init != nullptr) { - Entity *entity = check_entity_from_ident_or_selector(ctx, init); + Entity *entity = check_entity_from_ident_or_selector(ctx, init, false); if (entity != nullptr && entity->kind == Entity_TypeName) { // @TypeAliasingProblem // NOTE(bill, 2022-02-03): This is used to solve the problem caused by type aliases diff --git a/src/check_expr.cpp b/src/check_expr.cpp index e1c9bde84..d51444b4d 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -4082,11 +4082,11 @@ bool is_entity_declared_for_selector(Entity *entity, Scope *import_scope, bool * } // NOTE(bill, 2022-02-03): see `check_const_decl` for why it exists reasoning -Entity *check_entity_from_ident_or_selector(CheckerContext *c, Ast *node) { +Entity *check_entity_from_ident_or_selector(CheckerContext *c, Ast *node, bool ident_only) { if (node->kind == Ast_Ident) { String name = node->Ident.token.string; return scope_lookup(c->scope, name); - } else if (node->kind == Ast_SelectorExpr) { + } else if (!ident_only) if (node->kind == Ast_SelectorExpr) { ast_node(se, SelectorExpr, node); if (se->token.kind == Token_ArrowRight) { return nullptr; diff --git a/src/checker.cpp b/src/checker.cpp index c90f357dd..188d68502 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -3670,7 +3670,7 @@ bool correct_single_type_alias(CheckerContext *c, Entity *e) { DeclInfo *d = e->decl_info; if (d != nullptr && d->init_expr != nullptr) { Ast *init = d->init_expr; - Entity *alias_of = check_entity_from_ident_or_selector(c, init); + Entity *alias_of = check_entity_from_ident_or_selector(c, init, true); if (alias_of != nullptr && alias_of->kind == Entity_TypeName) { e->kind = Entity_TypeName; return true; -- cgit v1.2.3 From cf246f65ff72db870313627b7db3b83601364385 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 5 Feb 2022 14:31:22 +0000 Subject: Add check for variables which are both shadowing and unused by default --- src/checker.cpp | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index 188d68502..b62ef7c4c 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -504,6 +504,7 @@ enum VettedEntityKind { VettedEntity_Unused, VettedEntity_Shadowed, + VettedEntity_Shadowed_And_Unused, }; struct VettedEntity { VettedEntityKind kind; @@ -625,12 +626,18 @@ void check_scope_usage(Checker *c, Scope *scope) { MUTEX_GUARD_BLOCK(scope->mutex) for_array(i, scope->elements.entries) { Entity *e = scope->elements.entries[i].value; if (e == nullptr) continue; - VettedEntity ve = {}; - if (vet_unused && check_vet_unused(c, e, &ve)) { - array_add(&vetted_entities, ve); - } - if (vet_shadowing && check_vet_shadowing(c, e, &ve)) { - array_add(&vetted_entities, ve); + VettedEntity ve_unused = {}; + VettedEntity ve_shadowed = {}; + bool is_unused = vet_unused && check_vet_unused(c, e, &ve_unused); + bool is_shadowed = vet_shadowing && check_vet_shadowing(c, e, &ve_shadowed); + if (is_unused && is_shadowed) { + VettedEntity ve_both = ve_shadowed; + ve_both.kind = VettedEntity_Shadowed_And_Unused; + array_add(&vetted_entities, ve_both); + } else if (is_unused) { + array_add(&vetted_entities, ve_unused); + } else if (is_shadowed) { + array_add(&vetted_entities, ve_shadowed); } } @@ -642,16 +649,18 @@ void check_scope_usage(Checker *c, Scope *scope) { Entity *other = ve.other; String name = e->token.string; - if (build_context.vet) { + if (ve.kind == VettedEntity_Shadowed_And_Unused) { + error(e->token, "'%.*s' declared but not used, possibly shadows declaration at line %d", LIT(name), other->token.pos.line); + } else if (build_context.vet) { switch (ve.kind) { case VettedEntity_Unused: error(e->token, "'%.*s' declared but not used", LIT(name)); break; case VettedEntity_Shadowed: if (e->flags&EntityFlag_Using) { - error(e->token, "Declaration of '%.*s' from 'using' shadows declaration at line %lld", LIT(name), cast(long long)other->token.pos.line); + error(e->token, "Declaration of '%.*s' from 'using' shadows declaration at line %d", LIT(name), other->token.pos.line); } else { - error(e->token, "Declaration of '%.*s' shadows declaration at line %lld", LIT(name), cast(long long)other->token.pos.line); + error(e->token, "Declaration of '%.*s' shadows declaration at line %d", LIT(name), other->token.pos.line); } break; default: -- cgit v1.2.3 From 3c2ed3bb69df24ba162e5f2ea8f61ee3f7fd8e2f Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 7 Feb 2022 11:37:13 +0000 Subject: Correct `//+private file` bug --- src/checker.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index b62ef7c4c..7fb4fdb29 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -3477,11 +3477,11 @@ void check_collect_value_decl(CheckerContext *c, Ast *decl) { if (entity_visibility_kind == EntityVisiblity_Public && (c->scope->flags&ScopeFlag_File) && c->scope->file) { - if (c->scope->file->flags & AstFile_IsPrivatePkg) { - entity_visibility_kind = EntityVisiblity_PrivateToPackage; - } else if (c->scope->file->flags & AstFile_IsPrivateFile) { + if (c->scope->file->flags & AstFile_IsPrivateFile) { entity_visibility_kind = EntityVisiblity_PrivateToFile; - } + } else if (c->scope->file->flags & AstFile_IsPrivatePkg) { + entity_visibility_kind = EntityVisiblity_PrivateToPackage; + } } if (entity_visibility_kind != EntityVisiblity_Public && !(c->scope->flags&ScopeFlag_File)) { -- cgit v1.2.3 From 0cc40db565a9c4b99e6fa0844b9ac512558626e4 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 8 Feb 2022 17:04:55 +0000 Subject: Begin work on support objc intrinsics --- src/check_builtin.cpp | 223 +++++++++++++++++++++++++++++++++++++++++- src/check_decl.cpp | 3 + src/checker.cpp | 36 +++++++ src/checker.hpp | 15 ++- src/checker_builtin_procs.hpp | 6 ++ src/entity.cpp | 1 + src/llvm_backend.cpp | 59 ++++++++++- src/llvm_backend.hpp | 6 +- src/llvm_backend_general.cpp | 8 +- src/llvm_backend_proc.cpp | 3 + src/llvm_backend_utility.cpp | 96 ++++++++++++++++++ src/types.cpp | 10 ++ 12 files changed, 459 insertions(+), 7 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index 1fb3d6037..8ada77b12 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -143,6 +143,219 @@ void check_or_return_split_types(CheckerContext *c, Operand *x, String const &na } +bool does_require_msgSend_stret(Type *return_type) { + if (return_type == nullptr) { + return false; + } + if (build_context.metrics.arch == TargetArch_i386 || build_context.metrics.arch == TargetArch_amd64) { + i64 struct_limit = type_size_of(t_uintptr) << 1; + return type_size_of(return_type) > struct_limit; + } + if (build_context.metrics.arch == TargetArch_arm64) { + return false; + } + + // if (build_context.metrics.arch == TargetArch_arm32) { + // i64 struct_limit = type_size_of(t_uintptr); + // // NOTE(bill): This is technically wrong + // return is_type_struct(return_type) && !is_type_raw_union(return_type) && type_size_of(return_type) > struct_limit; + // } + GB_PANIC("unsupported architecture"); + return false; +} + +ObjcMsgKind get_objc_proc_kind(Type *return_type) { + if (return_type == nullptr) { + return ObjcMsg_normal; + } + + if (build_context.metrics.arch == TargetArch_i386 || build_context.metrics.arch == TargetArch_amd64) { + if (is_type_float(return_type)) { + return ObjcMsg_fpret; + } + if (build_context.metrics.arch == TargetArch_amd64) { + if (is_type_complex(return_type)) { + // URL: https://github.com/opensource-apple/objc4/blob/cd5e62a5597ea7a31dccef089317abb3a661c154/runtime/message.h#L143-L159 + return ObjcMsg_fpret; + } + } + } + if (build_context.metrics.arch != TargetArch_arm64) { + if (does_require_msgSend_stret(return_type)) { + return ObjcMsg_stret; + } + } + return ObjcMsg_normal; +} + +void add_objc_proc_type(CheckerContext *c, Ast *call, Type *return_type, Slice param_types) { + ObjcMsgKind kind = get_objc_proc_kind(return_type); + + Scope *scope = create_scope(c->info, nullptr); + + // NOTE(bill, 2022-02-08): the backend's ABI handling should handle this correctly, I hope + Type *params = alloc_type_tuple(); + { + auto variables = array_make(permanent_allocator(), 0, param_types.count); + + for_array(i, param_types) { + Type *type = param_types[i]; + Entity *param = alloc_entity_param(scope, blank_token, type, false, true); + array_add(&variables, param); + } + params->Tuple.variables = slice_from_array(variables); + } + + Type *results = alloc_type_tuple(); + if (return_type) { + auto variables = array_make(permanent_allocator(), 1); + results->Tuple.variables = slice_from_array(variables); + Entity *param = alloc_entity_param(scope, blank_token, return_type, false, true); + results->Tuple.variables[0] = param; + } + + + ObjcMsgData data = {}; + data.kind = kind; + data.proc_type = alloc_type_proc(scope, params, param_types.count, results, results->Tuple.variables.count, false, ProcCC_CDecl); + + mutex_lock(&c->info->objc_types_mutex); + map_set(&c->info->objc_msgSend_types, call, data); + mutex_unlock(&c->info->objc_types_mutex); + + add_package_dependency(c, "runtime", "objc_lookUpClass"); + add_package_dependency(c, "runtime", "sel_registerName"); + + add_package_dependency(c, "runtime", "objc_msgSend"); + add_package_dependency(c, "runtime", "objc_msgSend_fpret"); + add_package_dependency(c, "runtime", "objc_msgSend_fp2ret"); + add_package_dependency(c, "runtime", "objc_msgSend_stret"); +} + +bool check_builtin_objc_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 id, Type *type_hint) { + auto const is_constant_string = [](CheckerContext *c, String const &builtin_name, Ast *expr, String *name_) -> bool { + Operand op = {}; + check_expr(c, &op, expr); + if (op.mode == Addressing_Constant && op.value.kind == ExactValue_String) { + if (name_) *name_ = op.value.value_string; + return true; + } + gbString e = expr_to_string(op.expr); + gbString t = type_to_string(op.type); + error(op.expr, "'%.*s' expected a constant string value, got %s of type %s", LIT(builtin_name), e, t); + gb_string_free(t); + gb_string_free(e); + return false; + }; + String builtin_name = builtin_procs[id].name; + + if (build_context.metrics.os != TargetOs_darwin) { + error(call, "'%.*s' only works on darwin", LIT(builtin_name)); + return false; + } + + + ast_node(ce, CallExpr, call); + switch (id) { + default: + GB_PANIC("Implement objective built-in procedure: %.*s", LIT(builtin_name)); + return false; + + case BuiltinProc_objc_send: { + Type *return_type = nullptr; + + Operand rt = {}; + check_expr_or_type(c, &rt, ce->args[0]); + if (rt.mode == Addressing_Type) { + return_type = rt.type; + } else if (is_operand_nil(rt)) { + return_type = nullptr; + } else { + gbString e = expr_to_string(rt.expr); + error(rt.expr, "'%.*s' expected a type or nil to define the return type of the Objective-C call, got %s", LIT(builtin_name), e); + gb_string_free(e); + return false; + } + + operand->type = return_type; + operand->mode = return_type ? Addressing_Value : Addressing_NoValue; + + String class_name = {}; + String sel_name = {}; + + Type *sel_type = t_objc_SEL; + Operand self = {}; + check_expr_or_type(c, &self, ce->args[1]); + if (self.mode == Addressing_Type) { + if (!internal_check_is_assignable_to(self.type, t_objc_object)) { + gbString t = type_to_string(self.type); + error(self.expr, "'%.*s' expected a type or value derived from intrinsics.objc_object, got type %s", LIT(builtin_name), t); + gb_string_free(t); + return false; + } + if (!(self.type->kind == Type_Named && + self.type->Named.type_name != nullptr && + self.type->Named.type_name->TypeName.objc_class_name != "")) { + gbString t = type_to_string(self.type); + error(self.expr, "'%.*s' expected a named type with the attribute @(obj_class=) , got type %s", LIT(builtin_name), t); + gb_string_free(t); + return false; + } + + sel_type = t_objc_Class; + } else if (!is_operand_value(self) || !check_is_assignable_to(c, &self, t_objc_id)) { + gbString e = expr_to_string(self.expr); + gbString t = type_to_string(self.type); + error(self.expr, "'%.*s'3 expected a type or value derived from intrinsics.objc_object, got '%s' of type %s %d", LIT(builtin_name), e, t, self.type->kind); + gb_string_free(t); + gb_string_free(e); + return false; + } else if (!is_type_pointer(self.type)) { + gbString e = expr_to_string(self.expr); + gbString t = type_to_string(self.type); + error(self.expr, "'%.*s' expected a pointer of a value derived from intrinsics.objc_object, got '%s' of type %s", LIT(builtin_name), e, t); + gb_string_free(t); + gb_string_free(e); + return false; + } else { + Type *type = type_deref(self.type); + if (!(type->kind == Type_Named && + type->Named.type_name != nullptr && + type->Named.type_name->TypeName.objc_class_name != "")) { + gbString t = type_to_string(type); + error(self.expr, "'%.*s' expected a named type with the attribute @(obj_class=) , got type %s", LIT(builtin_name), t); + gb_string_free(t); + return false; + } + } + + + if (!is_constant_string(c, builtin_name, ce->args[2], &sel_name)) { + return false; + } + + isize const arg_offset = 1; + auto param_types = slice_make(permanent_allocator(), ce->args.count-arg_offset); + param_types[0] = t_objc_id; + param_types[1] = sel_type; + + for (isize i = 2+arg_offset; i < ce->args.count; i++) { + Operand x = {}; + check_expr(c, &x, ce->args[i]); + param_types[i-arg_offset] = x.type; + } + + add_objc_proc_type(c, call, return_type, param_types); + + return true; + } break; + + case BuiltinProc_objc_create: { + GB_PANIC("TODO: BuiltinProc_objc_create"); + return false; + } break; + } +} bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 id, Type *type_hint) { ast_node(ce, CallExpr, call); @@ -179,6 +392,8 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 case BuiltinProc_len: case BuiltinProc_min: case BuiltinProc_max: + case BuiltinProc_objc_send: + case BuiltinProc_objc_create: // NOTE(bill): The first arg may be a Type, this will be checked case by case break; @@ -202,7 +417,7 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 break; } - String builtin_name = builtin_procs[id].name;; + String builtin_name = builtin_procs[id].name; if (ce->args.count > 0) { @@ -219,6 +434,10 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 GB_PANIC("Implement built-in procedure: %.*s", LIT(builtin_name)); break; + case BuiltinProc_objc_send: + case BuiltinProc_objc_create: + return check_builtin_objc_procedure(c, operand, call, id, type_hint); + case BuiltinProc___entry_point: operand->mode = Addressing_NoValue; operand->type = nullptr; @@ -3815,6 +4034,8 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 operand->type = t_hasher_proc; break; } + + } return true; diff --git a/src/check_decl.cpp b/src/check_decl.cpp index f6dade812..243dbbbc6 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -338,6 +338,9 @@ void check_type_decl(CheckerContext *ctx, Entity *e, Ast *init_expr, Type *def) if (decl != nullptr) { AttributeContext ac = {}; check_decl_attributes(ctx, decl->attributes, type_decl_attribute, &ac); + if (e->kind == Entity_TypeName && ac.objc_class != "") { + e->TypeName.objc_class_name = ac.objc_class; + } } diff --git a/src/checker.cpp b/src/checker.cpp index 7fb4fdb29..2ab487592 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -841,6 +841,17 @@ void add_global_enum_constant(Slice const &fields, char const *name, i GB_PANIC("Unfound enum value for global constant: %s %lld", name, cast(long long)value); } +Type *add_global_type_name(Scope *scope, String const &type_name, Type *backing_type) { + Entity *e = alloc_entity_type_name(scope, make_token_ident(type_name), nullptr, EntityState_Resolved); + Type *named_type = alloc_type_named(type_name, backing_type, e); + e->type = named_type; + set_base_type(named_type, backing_type); + if (scope_insert(scope, e)) { + compiler_error("double declaration of %.*s", LIT(e->token.string)); + } + return named_type; +} + void init_universal(void) { BuildContext *bc = &build_context; @@ -985,6 +996,17 @@ void init_universal(void) { t_f64_ptr = alloc_type_pointer(t_f64); t_u8_slice = alloc_type_slice(t_u8); t_string_slice = alloc_type_slice(t_string); + + // intrinsics types for objective-c stuff + { + t_objc_object = add_global_type_name(intrinsics_pkg->scope, str_lit("objc_object"), alloc_type_struct()); + t_objc_selector = add_global_type_name(intrinsics_pkg->scope, str_lit("objc_selector"), alloc_type_struct()); + t_objc_class = add_global_type_name(intrinsics_pkg->scope, str_lit("objc_class"), alloc_type_struct()); + + t_objc_id = alloc_type_pointer(t_objc_object); + t_objc_SEL = alloc_type_pointer(t_objc_selector); + t_objc_Class = alloc_type_pointer(t_objc_class); + } } @@ -1041,6 +1063,9 @@ void init_checker_info(CheckerInfo *i) { semaphore_init(&i->collect_semaphore); mpmc_init(&i->intrinsics_entry_point_usage, a, 1<<10); // just waste some memory here, even if it probably never used + + mutex_init(&i->objc_types_mutex); + map_init(&i->objc_msgSend_types, a); } void destroy_checker_info(CheckerInfo *i) { @@ -1073,6 +1098,9 @@ void destroy_checker_info(CheckerInfo *i) { mutex_destroy(&i->type_and_value_mutex); mutex_destroy(&i->identifier_uses_mutex); mutex_destroy(&i->foreign_mutex); + + mutex_destroy(&i->objc_types_mutex); + map_destroy(&i->objc_msgSend_types); } CheckerContext make_checker_context(Checker *c) { @@ -3161,6 +3189,14 @@ DECL_ATTRIBUTE_PROC(type_decl_attribute) { } else if (name == "private") { // NOTE(bill): Handled elsewhere `check_collect_value_decl` return true; + } else if (name == "objc_class") { + ExactValue ev = check_decl_attribute_value(c, value); + if (ev.kind != ExactValue_String || ev.value_string == "") { + error(elem, "Expected a non-empty string value for '%.*s'", LIT(name)); + } else { + ac->objc_class = ev.value_string; + } + return true; } return false; } diff --git a/src/checker.hpp b/src/checker.hpp index 9a8753efd..b812e10a4 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -107,6 +107,7 @@ struct AttributeContext { String thread_local_model; String deprecated_message; String warning_message; + String objc_class; DeferredProcedure deferred_procedure; bool is_export : 1; bool is_static : 1; @@ -267,6 +268,17 @@ struct UntypedExprInfo { typedef PtrMap UntypedExprInfoMap; typedef MPMCQueue ProcBodyQueue; +enum ObjcMsgKind : u32 { + ObjcMsg_normal, + ObjcMsg_fpret, + ObjcMsg_fp2ret, + ObjcMsg_stret, +}; +struct ObjcMsgData { + ObjcMsgKind kind; + Type *proc_type; +}; + // CheckerInfo stores all the symbol information for a type-checked program struct CheckerInfo { Checker *checker; @@ -340,7 +352,8 @@ struct CheckerInfo { MPMCQueue intrinsics_entry_point_usage; - + BlockingMutex objc_types_mutex; + PtrMap objc_msgSend_types; }; struct CheckerContext { diff --git a/src/checker_builtin_procs.hpp b/src/checker_builtin_procs.hpp index d833a055f..1a9d7d7a0 100644 --- a/src/checker_builtin_procs.hpp +++ b/src/checker_builtin_procs.hpp @@ -250,6 +250,9 @@ BuiltinProc__type_end, BuiltinProc___entry_point, + BuiltinProc_objc_send, + BuiltinProc_objc_create, + BuiltinProc_COUNT, }; gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = { @@ -500,4 +503,7 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = { {STR_LIT(""), 0, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, {STR_LIT("__entry_point"), 0, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, + + {STR_LIT("objc_send"), 3, true, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("objc_create"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, }; diff --git a/src/entity.cpp b/src/entity.cpp index 8327a517e..4d5b3b9e1 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -186,6 +186,7 @@ struct Entity { Type * type_parameter_specialization; String ir_mangled_name; bool is_type_alias; + String objc_class_name; } TypeName; struct { u64 tags; diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 304effb7f..7941c65a3 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -652,7 +652,53 @@ lbProcedure *lb_create_startup_type_info(lbModule *m) { return p; } -lbProcedure *lb_create_startup_runtime(lbModule *main_module, lbProcedure *startup_type_info, Array &global_variables) { // Startup Runtime +lbProcedure *lb_create_objc_names(lbModule *main_module) { + if (build_context.metrics.os != TargetOs_darwin) { + return nullptr; + } + Type *proc_type = alloc_type_proc(nullptr, nullptr, 0, nullptr, 0, false, ProcCC_CDecl); + lbProcedure *p = lb_create_dummy_procedure(main_module, str_lit("__$init_objc_names"), proc_type); + p->is_startup = true; + return p; +} + +void lb_finalize_objc_names(lbProcedure *p) { + if (p == nullptr) { + return; + } + lbModule *m = p->module; + + 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); + + LLVMSetLinkage(p->value, LLVMInternalLinkage); + lb_begin_procedure_body(p); + for_array(i, m->objc_classes.entries) { + auto const &entry = m->objc_classes.entries[i]; + String name = entry.key.string; + auto args = array_make(permanent_allocator(), 1); + 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]; + String name = entry.key.string; + auto args = array_make(permanent_allocator(), 1); + args[0] = lb_const_value(m, t_cstring, exact_value_string(name)); + lbValue ptr = lb_emit_runtime_call(p, "sel_registerName", args); + lb_addr_store(p, entry.value, ptr); + } + + lb_end_procedure_body(p); + + lb_run_function_pass_manager(default_function_pass_manager, p); + +} + +lbProcedure *lb_create_startup_runtime(lbModule *main_module, lbProcedure *startup_type_info, lbProcedure *objc_names, Array &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); @@ -666,6 +712,10 @@ lbProcedure *lb_create_startup_runtime(lbModule *main_module, lbProcedure *start LLVMBuildCall2(p->builder, LLVMGetElementType(lb_type(main_module, startup_type_info->type)), startup_type_info->value, nullptr, 0, ""); + if (objc_names) { + LLVMBuildCall2(p->builder, LLVMGetElementType(lb_type(main_module, objc_names->type)), objc_names->value, nullptr, 0, ""); + } + for_array(i, global_variables) { auto *var = &global_variables[i]; if (var->is_initialized) { @@ -1570,8 +1620,10 @@ void lb_generate_code(lbGenerator *gen) { TIME_SECTION("LLVM Runtime Type Information Creation"); lbProcedure *startup_type_info = lb_create_startup_type_info(default_module); + lbProcedure *objc_names = lb_create_objc_names(default_module); + TIME_SECTION("LLVM Runtime Startup Creation (Global Variables)"); - lbProcedure *startup_runtime = lb_create_startup_runtime(default_module, startup_type_info, global_variables); + lbProcedure *startup_runtime = lb_create_startup_runtime(default_module, startup_type_info, objc_names, global_variables); gb_unused(startup_runtime); TIME_SECTION("LLVM Global Procedures and Types"); @@ -1650,6 +1702,8 @@ void lb_generate_code(lbGenerator *gen) { } } + lb_finalize_objc_names(objc_names); + if (build_context.ODIN_DEBUG) { TIME_SECTION("LLVM Debug Info Complete Types and Finalize"); for_array(j, gen->modules.entries) { @@ -1662,6 +1716,7 @@ void lb_generate_code(lbGenerator *gen) { } + TIME_SECTION("LLVM Function Pass"); for_array(i, gen->modules.entries) { lbModule *m = gen->modules.entries[i].value; diff --git a/src/llvm_backend.hpp b/src/llvm_backend.hpp index d7093bc63..087cda22a 100644 --- a/src/llvm_backend.hpp +++ b/src/llvm_backend.hpp @@ -144,6 +144,9 @@ struct lbModule { PtrMap debug_values; Array debug_incomplete_types; + + StringMap objc_classes; + StringMap objc_selectors; }; struct lbGenerator { @@ -293,7 +296,6 @@ struct lbProcedure { bool lb_init_generator(lbGenerator *gen, Checker *c); -void lb_generate_module(lbGenerator *gen); String lb_mangle_name(lbModule *m, Entity *e); String lb_get_entity_name(lbModule *m, Entity *e, String name = {}); @@ -366,7 +368,7 @@ lbContextData *lb_push_context_onto_stack(lbProcedure *p, lbAddr ctx); lbContextData *lb_push_context_onto_stack_from_implicit_parameter(lbProcedure *p); -lbAddr lb_add_global_generated(lbModule *m, Type *type, lbValue value={}); +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, i32 param_index=0, bool force_no_init=false); void lb_add_foreign_library_path(lbModule *m, Entity *e); diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index 2fc21b534..1c98aa77f 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -72,6 +72,9 @@ void lb_init_module(lbModule *m, Checker *c) { map_init(&m->debug_values, a); array_init(&m->debug_incomplete_types, a, 0, 1024); + + string_map_init(&m->objc_classes, a); + string_map_init(&m->objc_selectors, a); } bool lb_init_generator(lbGenerator *gen, Checker *c) { @@ -2450,7 +2453,7 @@ lbValue lb_find_procedure_value_from_entity(lbModule *m, Entity *e) { return {}; } -lbAddr lb_add_global_generated(lbModule *m, Type *type, lbValue value) { +lbAddr lb_add_global_generated(lbModule *m, Type *type, lbValue value, Entity **entity_) { GB_ASSERT(type != nullptr); type = default_type(type); @@ -2476,6 +2479,9 @@ lbAddr lb_add_global_generated(lbModule *m, Type *type, lbValue value) { lb_add_entity(m, e, g); lb_add_member(m, name, g); + + if (entity_) *entity_ = e; + return lb_addr(g); } diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index 7a6fac603..6de0aaed7 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -2106,6 +2106,9 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, res.type = t_uintptr; return res; } + + case BuiltinProc_objc_send: + return lb_handle_obj_send(p, expr); } GB_PANIC("Unhandled built-in procedure %.*s", LIT(builtin_procs[id].name)); diff --git a/src/llvm_backend_utility.cpp b/src/llvm_backend_utility.cpp index 7e2bd7daa..d92f711ba 100644 --- a/src/llvm_backend_utility.cpp +++ b/src/llvm_backend_utility.cpp @@ -1819,3 +1819,99 @@ void lb_set_wasm_export_attributes(LLVMValueRef value, String export_name) { LLVMSetVisibility(value, LLVMDefaultVisibility); LLVMAddTargetDependentFunctionAttr(value, "wasm-export-name", alloc_cstring(permanent_allocator(), export_name)); } + + +lbValue lb_lookup_runtime_procedure(lbModule *m, String const &name); + +lbValue lb_handle_obj_id(lbProcedure *p, Ast *expr) { + TypeAndValue const &tav = type_and_value_of_expr(expr); + if (tav.mode == Addressing_Type) { + Type *type = tav.type; + GB_ASSERT_MSG(type->kind == Type_Named, "%s", type_to_string(type)); + Entity *e = type->Named.type_name; + GB_ASSERT(e->kind == Entity_TypeName); + String name = e->TypeName.objc_class_name; + + lbAddr *found = string_map_get(&p->module->objc_classes, name); + if (found) { + return lb_addr_load(p, *found); + } else { + lbModule *default_module = &p->module->gen->default_module; + Entity *e = nullptr; + lbAddr default_addr = lb_add_global_generated(default_module, t_objc_Class, {}, &e); + + lbValue ptr = lb_find_value_from_entity(p->module, e); + lbAddr local_addr = lb_addr(ptr); + + string_map_set(&default_module->objc_classes, name, default_addr); + if (default_module != p->module) { + string_map_set(&p->module->objc_classes, name, local_addr); + } + return lb_addr_load(p, local_addr); + } + } + + return lb_build_expr(p, expr); +} + + +lbValue lb_handle_obj_selector(lbProcedure *p, String const &name) { + lbAddr *found = string_map_get(&p->module->objc_selectors, name); + if (found) { + return lb_addr_load(p, *found); + } else { + lbModule *default_module = &p->module->gen->default_module; + Entity *e = nullptr; + lbAddr default_addr = lb_add_global_generated(default_module, t_objc_SEL, {}, &e); + + lbValue ptr = lb_find_value_from_entity(p->module, e); + lbAddr local_addr = lb_addr(ptr); + + string_map_set(&default_module->objc_selectors, name, default_addr); + if (default_module != p->module) { + string_map_set(&p->module->objc_selectors, name, local_addr); + } + return lb_addr_load(p, local_addr); + } +} + + +lbValue lb_handle_obj_send(lbProcedure *p, Ast *expr) { + ast_node(ce, CallExpr, expr); + + lbModule *m = p->module; + CheckerInfo *info = m->info; + ObjcMsgData data = map_must_get(&info->objc_msgSend_types, expr); + GB_ASSERT(data.proc_type != nullptr); + + GB_ASSERT(ce->args.count >= 3); + auto args = array_make(permanent_allocator(), 0, ce->args.count-1); + + lbValue id = lb_handle_obj_id(p, ce->args[1]); + Ast *sel_expr = ce->args[2]; + GB_ASSERT(sel_expr->tav.value.kind == ExactValue_String); + lbValue sel = lb_handle_obj_selector(p, sel_expr->tav.value.value_string); + + array_add(&args, id); + array_add(&args, sel); + for (isize i = 3; i < ce->args.count; i++) { + lbValue arg = lb_build_expr(p, ce->args[i]); + array_add(&args, arg); + } + + + lbValue the_proc = {}; + switch (data.kind) { + default: + GB_PANIC("unhandled ObjcMsgKind %u", data.kind); + break; + case ObjcMsg_normal: the_proc = lb_lookup_runtime_procedure(m, str_lit("objc_msgSend")); break; + case ObjcMsg_fpret: the_proc = lb_lookup_runtime_procedure(m, str_lit("objc_msgSend_fpret")); break; + case ObjcMsg_fp2ret: the_proc = lb_lookup_runtime_procedure(m, str_lit("objc_msgSend_fp2ret")); break; + case ObjcMsg_stret: the_proc = lb_lookup_runtime_procedure(m, str_lit("objc_msgSend_stret")); break; + } + + the_proc = lb_emit_conv(p, the_proc, data.proc_type); + + return lb_emit_call(p, the_proc, args); +} diff --git a/src/types.cpp b/src/types.cpp index 9ee6ba359..cdb31c6e1 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -685,6 +685,16 @@ gb_global Type *t_map_header = nullptr; gb_global Type *t_equal_proc = nullptr; gb_global Type *t_hasher_proc = nullptr; +gb_global Type *t_objc_object = nullptr; +gb_global Type *t_objc_selector = nullptr; +gb_global Type *t_objc_class = nullptr; + +gb_global Type *t_objc_id = nullptr; +gb_global Type *t_objc_SEL = nullptr; +gb_global Type *t_objc_Class = nullptr; + + + gb_global RecursiveMutex g_type_mutex; struct TypePath; -- cgit v1.2.3 From f8afda3b221f6c2279a393c2c0fb8ab7ea1d59df Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 11 Feb 2022 22:54:51 +0000 Subject: Add more objc attributes --- core/sys/darwin/Foundation/NSArray.odin | 36 ++++-- core/sys/darwin/Foundation/NSAutoreleasePool.odin | 15 ++- core/sys/darwin/Foundation/NSBundle.odin | 56 ++++++-- core/sys/darwin/Foundation/NSData.odin | 12 ++ core/sys/darwin/Foundation/NSDate.odin | 12 ++ core/sys/darwin/Foundation/NSDictionary.odin | 18 +++ core/sys/darwin/Foundation/NSEnumerator.odin | 15 ++- core/sys/darwin/Foundation/NSError.odin | 22 +++- core/sys/darwin/Foundation/NSLock.odin | 24 ++++ core/sys/darwin/Foundation/NSNotification.odin | 15 +++ core/sys/darwin/Foundation/NSNumber.odin | 149 ++++++++++++---------- core/sys/darwin/Foundation/NSObject.odin | 28 ++-- core/sys/darwin/Foundation/NSString.odin | 24 ++++ core/sys/darwin/Foundation/NSURL.odin | 12 ++ src/check_builtin.cpp | 8 +- src/check_decl.cpp | 63 +++++++++ src/check_type.cpp | 2 + src/checker.cpp | 50 +++++++- src/checker.hpp | 6 +- src/entity.cpp | 23 ++++ src/llvm_backend_expr.cpp | 11 +- src/main.cpp | 32 +---- src/string.cpp | 31 +++++ src/types.cpp | 62 +++++++++ 24 files changed, 586 insertions(+), 140 deletions(-) (limited to 'src/checker.cpp') diff --git a/core/sys/darwin/Foundation/NSArray.odin b/core/sys/darwin/Foundation/NSArray.odin index 435e239a2..e17223ff7 100644 --- a/core/sys/darwin/Foundation/NSArray.odin +++ b/core/sys/darwin/Foundation/NSArray.odin @@ -3,26 +3,40 @@ package objc_Foundation import "core:intrinsics" @(objc_class="NSArray") -Array :: struct($T: typeid) where intrinsics.type_is_pointer(T), intrinsics.type_is_subtype_of(T, ^Object) { - using _: Copying(Array(T)), +Array :: struct { + using _: Copying(Array), } -Array_initWithObjects :: proc(self: ^$A/Array($T), objects: [^]^Object, count: UInteger) -> ^A { - return msgSend(^A, "initWithObjects:count:", objects, count) +@(objc_type=Array, objc_class_name="alloc") +Array_alloc :: proc() -> ^Array { + return msgSend(^Array, Array, "alloc") } -Array_initWithCoder :: proc(self: ^$A/Array($T), coder: ^Coder) -> ^A { - return msgSend(^A, "initWithCoder:", coder) +@(objc_type=Array, objc_name="init") +Array_init :: proc(self: ^Array) -> ^Array { + return msgSend(^Array, self, "init") } -Array_objectAtIndex :: proc(self: ^Array($T), index: UInteger) -> ^Object { - return msgSend(^Object, self, "objectAtIndex:", index) +@(objc_type=Array, objc_name="initWithObjects") +Array_initWithObjects :: proc(self: ^Array, objects: [^]^Object, count: UInteger) -> ^Array { + return msgSend(^Array, self, "initWithObjects:count:", objects, count) +} + +@(objc_type=Array, objc_name="initWithCoder") +Array_initWithCoder :: proc(self: ^Array, coder: ^Coder) -> ^Array { + return msgSend(^Array, self, "initWithCoder:", coder) } -Array_object :: proc(self: ^Array($T), index: UInteger) -> T { - return (T)(Array_objectAtIndex(self, index)) +@(objc_type=Array, objc_name="object") +Array_object :: proc(self: ^Array, index: UInteger) -> ^Object { + return msgSend(^Object, self, "objectAtIndex:", index) +} +@(objc_type=Array, objc_name="objectAs") +Array_objectAs :: proc(self: ^Array, index: UInteger, $T: typeid) -> T where intrinsics.type_is_pointer(T), intrinsics.type_is_subtype_of(T, ^Object) { + return (T)(Array_object(self, index)) } -Array_count :: proc(self: ^Array($T)) -> UInteger { +@(objc_type=Array, objc_name="count") +Array_count :: proc(self: ^Array) -> UInteger { return msgSend(UInteger, self, "count") } diff --git a/core/sys/darwin/Foundation/NSAutoreleasePool.odin b/core/sys/darwin/Foundation/NSAutoreleasePool.odin index 47cbc0e9a..17ec88ba1 100644 --- a/core/sys/darwin/Foundation/NSAutoreleasePool.odin +++ b/core/sys/darwin/Foundation/NSAutoreleasePool.odin @@ -3,12 +3,25 @@ package objc_Foundation @(objc_class="NSAutoreleasePool") AutoreleasePool :: struct {using _: Object} +@(objc_type=AutoreleasePool, objc_class_name="alloc") +AutoreleasePool_alloc :: proc() -> ^AutoreleasePool { + return msgSend(^AutoreleasePool, AutoreleasePool, "alloc") +} + +@(objc_type=AutoreleasePool, objc_name="init") +AutoreleasePool_init :: proc(self: ^AutoreleasePool) -> ^AutoreleasePool { + return msgSend(^AutoreleasePool, self, "init") +} + +@(objc_type=AutoreleasePool, objc_name="drain") AutoreleasePool_drain :: proc(self: ^AutoreleasePool) { msgSend(nil, self, "drain") } +@(objc_type=AutoreleasePool, objc_name="addObject") AutoreleasePool_addObject :: proc(self: ^AutoreleasePool, obj: ^Object) { msgSend(nil, self, "addObject:", obj) } +@(objc_type=AutoreleasePool, objc_name="showPools") AutoreleasePool_showPools :: proc(self: ^AutoreleasePool, obj: ^Object) { msgSend(nil, self, "showPools") } @@ -16,5 +29,5 @@ AutoreleasePool_showPools :: proc(self: ^AutoreleasePool, obj: ^Object) { @(deferred_out=AutoreleasePool_drain) scoped_autoreleasepool :: proc() -> ^AutoreleasePool { - return init(alloc(AutoreleasePool)) + return AutoreleasePool.alloc()->init() } \ No newline at end of file diff --git a/core/sys/darwin/Foundation/NSBundle.odin b/core/sys/darwin/Foundation/NSBundle.odin index 375e15b65..a18809b7e 100644 --- a/core/sys/darwin/Foundation/NSBundle.odin +++ b/core/sys/darwin/Foundation/NSBundle.odin @@ -3,98 +3,120 @@ package objc_Foundation @(objc_class="NSBundle") Bundle :: struct { using _: Object } +@(objc_type=Bundle, objc_class_name="mainBundle") Bundle_mainBundle :: proc() -> ^Bundle { return msgSend(^Bundle, Bundle, "mainBundle") } +@(objc_type=Bundle, objc_class_name="bundleWithPath") Bundle_bundleWithPath :: proc(path: ^String) -> ^Bundle { return msgSend(^Bundle, Bundle, "bundleWithPath:", path) } +@(objc_type=Bundle, objc_class_name="bundleWithURL") Bundle_bundleWithURL :: proc(url: ^URL) -> ^Bundle { return msgSend(^Bundle, Bundle, "bundleWithUrl:", url) } -Bundle_bundle :: proc{ - Bundle_bundleWithPath, - Bundle_bundleWithURL, + + +@(objc_type=Bundle, objc_class_name="alloc") +Bundle_alloc :: proc() -> ^Bundle { + return msgSend(^Bundle, Bundle, "alloc") } +@(objc_type=Bundle, objc_name="init") +Bundle_init :: proc(self: ^Bundle) -> ^Bundle { + return msgSend(^Bundle, self, "init") +} +@(objc_type=Bundle, objc_name="initWithPath") Bundle_initWithPath :: proc(self: ^Bundle, path: ^String) -> ^Bundle { return msgSend(^Bundle, self, "initWithPath:", path) } +@(objc_type=Bundle, objc_name="initWithURL") Bundle_initWithURL :: proc(self: ^Bundle, url: ^URL) -> ^Bundle { return msgSend(^Bundle, self, "initWithUrl:", url) } -Bundle_init :: proc{ - Bundle_initWithPath, - Bundle_initWithURL, -} - -Bundle_allBundles :: proc() -> (all: ^Array(^Bundle)) { +@(objc_type=Bundle, objc_name="allBundles") +Bundle_allBundles :: proc() -> (all: ^Array) { return msgSend(type_of(all), Bundle, "allBundles") } -Bundle_allFrameworks :: proc() -> (all: ^Array(^Object)) { +@(objc_type=Bundle, objc_name="allFrameworks") +Bundle_allFrameworks :: proc() -> (all: ^Array) { return msgSend(type_of(all), Bundle, "allFrameworks") } +@(objc_type=Bundle, objc_name="load") Bundle_load :: proc(self: ^Bundle) -> BOOL { return msgSend(BOOL, self, "load") } +@(objc_type=Bundle, objc_name="unload") Bundle_unload :: proc(self: ^Bundle) -> BOOL { return msgSend(BOOL, self, "unload") } +@(objc_type=Bundle, objc_name="isLoaded") Bundle_isLoaded :: proc(self: ^Bundle) -> BOOL { return msgSend(BOOL, self, "isLoaded") } +@(objc_type=Bundle, objc_name="preflightAndReturnError") Bundle_preflightAndReturnError :: proc(self: ^Bundle) -> (ok: BOOL, error: ^Error) { ok = msgSend(BOOL, self, "preflightAndReturnError:", &error) return } +@(objc_type=Bundle, objc_name="loadAndReturnError") Bundle_loadAndReturnError :: proc(self: ^Bundle) -> (ok: BOOL, error: ^Error) { ok = msgSend(BOOL, self, "loadAndReturnError:", &error) return } +@(objc_type=Bundle, objc_name="bundleURL") Bundle_bundleURL :: proc(self: ^Bundle) -> ^URL { return msgSend(^URL, self, "bundleURL") } +@(objc_type=Bundle, objc_name="resourceURL") Bundle_resourceURL :: proc(self: ^Bundle) -> ^URL { return msgSend(^URL, self, "resourceURL") } +@(objc_type=Bundle, objc_name="executableURL") Bundle_executableURL :: proc(self: ^Bundle) -> ^URL { return msgSend(^URL, self, "executableURL") } +@(objc_type=Bundle, objc_name="URLForAuxiliaryExecutable") Bundle_URLForAuxiliaryExecutable :: proc(self: ^Bundle, executableName: ^String) -> ^URL { return msgSend(^URL, self, "URLForAuxiliaryExecutable:", executableName) } +@(objc_type=Bundle, objc_name="privateFrameworksURL") Bundle_privateFrameworksURL :: proc(self: ^Bundle) -> ^URL { return msgSend(^URL, self, "privateFrameworksURL") } +@(objc_type=Bundle, objc_name="sharedFrameworksURL") Bundle_sharedFrameworksURL :: proc(self: ^Bundle) -> ^URL { return msgSend(^URL, self, "sharedFrameworksURL") } +@(objc_type=Bundle, objc_name="sharedSupportURL") Bundle_sharedSupportURL :: proc(self: ^Bundle) -> ^URL { return msgSend(^URL, self, "sharedSupportURL") } +@(objc_type=Bundle, objc_name="builtInPlugInsURL") Bundle_builtInPlugInsURL :: proc(self: ^Bundle) -> ^URL { return msgSend(^URL, self, "builtInPlugInsURL") } +@(objc_type=Bundle, objc_name="appStoreReceiptURL") Bundle_appStoreReceiptURL :: proc(self: ^Bundle) -> ^URL { return msgSend(^URL, self, "appStoreReceiptURL") } @@ -102,60 +124,74 @@ Bundle_appStoreReceiptURL :: proc(self: ^Bundle) -> ^URL { +@(objc_type=Bundle, objc_name="bundlePath") Bundle_bundlePath :: proc(self: ^Bundle) -> ^String { return msgSend(^String, self, "bundlePath") } +@(objc_type=Bundle, objc_name="resourcePath") Bundle_resourcePath :: proc(self: ^Bundle) -> ^String { return msgSend(^String, self, "resourcePath") } +@(objc_type=Bundle, objc_name="executablePath") Bundle_executablePath :: proc(self: ^Bundle) -> ^String { return msgSend(^String, self, "executablePath") } +@(objc_type=Bundle, objc_name="PathForAuxiliaryExecutable") Bundle_PathForAuxiliaryExecutable :: proc(self: ^Bundle, executableName: ^String) -> ^String { return msgSend(^String, self, "PathForAuxiliaryExecutable:", executableName) } +@(objc_type=Bundle, objc_name="privateFrameworksPath") Bundle_privateFrameworksPath :: proc(self: ^Bundle) -> ^String { return msgSend(^String, self, "privateFrameworksPath") } +@(objc_type=Bundle, objc_name="sharedFrameworksPath") Bundle_sharedFrameworksPath :: proc(self: ^Bundle) -> ^String { return msgSend(^String, self, "sharedFrameworksPath") } +@(objc_type=Bundle, objc_name="sharedSupportPath") Bundle_sharedSupportPath :: proc(self: ^Bundle) -> ^String { return msgSend(^String, self, "sharedSupportPath") } +@(objc_type=Bundle, objc_name="builtInPlugInsPath") Bundle_builtInPlugInsPath :: proc(self: ^Bundle) -> ^String { return msgSend(^String, self, "builtInPlugInsPath") } +@(objc_type=Bundle, objc_name="appStoreReceiptPath") Bundle_appStoreReceiptPath :: proc(self: ^Bundle) -> ^String { return msgSend(^String, self, "appStoreReceiptPath") } +@(objc_type=Bundle, objc_name="bundleIdentifier") Bundle_bundleIdentifier :: proc(self: ^Bundle) -> ^String { return msgSend(^String, self, "bundleIdentifier") } +@(objc_type=Bundle, objc_name="infoDictionary") Bundle_infoDictionary :: proc(self: ^Bundle) -> ^Dictionary { return msgSend(^Dictionary, self, "infoDictionary") } +@(objc_type=Bundle, objc_name="localizedInfoDictionary") Bundle_localizedInfoDictionary :: proc(self: ^Bundle) -> ^Dictionary { return msgSend(^Dictionary, self, "localizedInfoDictionary") } +@(objc_type=Bundle, objc_name="objectForInfoDictionaryKey") Bundle_objectForInfoDictionaryKey :: proc(self: ^Bundle, key: ^String) -> ^Object { return msgSend(^Object, self, "objectForInfoDictionaryKey:", key) } +@(objc_type=Bundle, objc_name="localizedStringForKey") Bundle_localizedStringForKey :: proc(self: ^Bundle, key: ^String, value: ^String = nil, tableName: ^String = nil) -> ^String { return msgSend(^String, self, "localizedStringForKey:value:table:", key, value, tableName) } diff --git a/core/sys/darwin/Foundation/NSData.odin b/core/sys/darwin/Foundation/NSData.odin index 93bb3ae0e..e28f6a644 100644 --- a/core/sys/darwin/Foundation/NSData.odin +++ b/core/sys/darwin/Foundation/NSData.odin @@ -3,10 +3,22 @@ package objc_Foundation @(objc_class="NSData") Data :: struct {using _: Copying(Data)} +@(objc_type=Data, objc_class_name="alloc") +Data_alloc :: proc() -> ^Data { + return msgSend(^Data, Data, "alloc") +} + +@(objc_type=Data, objc_name="init") +Data_init :: proc(self: ^Data) -> ^Data { + return msgSend(^Data, self, "init") +} + +@(objc_type=Data, objc_name="mutableBytes") Data_mutableBytes :: proc(self: ^Data) -> rawptr { return msgSend(rawptr, self, "mutableBytes") } +@(objc_type=Data, objc_name="length") Data_length :: proc(self: ^Data) -> UInteger { return msgSend(UInteger, self, "length") } \ No newline at end of file diff --git a/core/sys/darwin/Foundation/NSDate.odin b/core/sys/darwin/Foundation/NSDate.odin index 4b298ee24..85bb14c3e 100644 --- a/core/sys/darwin/Foundation/NSDate.odin +++ b/core/sys/darwin/Foundation/NSDate.odin @@ -3,6 +3,18 @@ package objc_Foundation @(objc_class="NSDate") Date :: struct {using _: Copying(Date)} +@(objc_type=Date, objc_class_name="alloc") +Date_alloc :: proc() -> ^Date { + return msgSend(^Date, Date, "alloc") +} + +@(objc_type=Date, objc_name="init") +Date_init :: proc(self: ^Date) -> ^Date { + return msgSend(^Date, self, "init") +} + + +@(objc_type=Date, objc_name="dateWithTimeIntervalSinceNow") Date_dateWithTimeIntervalSinceNow :: proc(secs: TimeInterval) -> ^Date { return msgSend(^Date, Date, "dateWithTimeIntervalSinceNow:", secs) } \ No newline at end of file diff --git a/core/sys/darwin/Foundation/NSDictionary.odin b/core/sys/darwin/Foundation/NSDictionary.odin index f82b8cffd..3eb378dc7 100644 --- a/core/sys/darwin/Foundation/NSDictionary.odin +++ b/core/sys/darwin/Foundation/NSDictionary.odin @@ -3,31 +3,49 @@ package objc_Foundation @(objc_class="NSDictionary") Dictionary :: struct {using _: Copying(Dictionary)} +@(objc_type=Dictionary, objc_class_name="dictionary") Dictionary_dictionary :: proc() -> ^Dictionary { return msgSend(^Dictionary, Dictionary, "dictionary") } +@(objc_type=Dictionary, objc_class_name="dictionaryWithObject") Dictionary_dictionaryWithObject :: proc(object: ^Object, forKey: ^Object) -> ^Dictionary { return msgSend(^Dictionary, Dictionary, "dictionaryWithObject:forKey:", object, forKey) } +@(objc_type=Dictionary, objc_class_name="dictionaryWithObjects") Dictionary_dictionaryWithObjects :: proc(objects: [^]^Object, forKeys: [^]^Object, count: UInteger) -> ^Dictionary { return msgSend(^Dictionary, Dictionary, "dictionaryWithObjects:forKeys:count", objects, forKeys, count) } +@(objc_type=Dictionary, objc_class_name="alloc") +Dictionary_alloc :: proc() -> ^Dictionary { + return msgSend(^Dictionary, Dictionary, "alloc") +} + +@(objc_type=Dictionary, objc_name="init") +Dictionary_init :: proc(self: ^Dictionary) -> ^Dictionary { + return msgSend(^Dictionary, self, "init") +} + + +@(objc_type=Dictionary, objc_name="initWithObjects") Dictionary_initWithObjects :: proc(self: ^Dictionary, objects: [^]^Object, forKeys: [^]^Object, count: UInteger) -> ^Dictionary { return msgSend(^Dictionary, self, "initWithObjects:forKeys:count", objects, forKeys, count) } +@(objc_type=Dictionary, objc_name="objectForKey") Dictionary_objectForKey :: proc(self: ^Dictionary, key: ^Object) -> ^Object { return msgSend(^Dictionary, self, "objectForKey:", key) } +@(objc_type=Dictionary, objc_name="count") Dictionary_count :: proc(self: ^Dictionary) -> UInteger { return msgSend(UInteger, self, "count") } +@(objc_type=Dictionary, objc_name="keyEnumerator") Dictionary_keyEnumerator :: proc(self: ^Dictionary, $KeyType: typeid) -> (enumerator: ^Enumerator(KeyType)) { return msgSend(type_of(enumerator), self, "keyEnumerator") } diff --git a/core/sys/darwin/Foundation/NSEnumerator.odin b/core/sys/darwin/Foundation/NSEnumerator.odin index b6adf2b98..8a5a32e69 100644 --- a/core/sys/darwin/Foundation/NSEnumerator.odin +++ b/core/sys/darwin/Foundation/NSEnumerator.odin @@ -18,6 +18,19 @@ Enumerator :: struct($T: typeid) where intrinsics.type_is_pointer(T), intrinsics using _: FastEnumeration, } + +@(objc_type=FastEnumeration, objc_class_name="alloc") +FastEnumeration_alloc :: proc() -> ^FastEnumeration { + return msgSend(^FastEnumeration, FastEnumeration, "alloc") +} + +@(objc_type=FastEnumeration, objc_name="init") +FastEnumeration_init :: proc(self: ^FastEnumeration) -> ^FastEnumeration { + return msgSend(^FastEnumeration, self, "init") +} + + +@(objc_type=FastEnumeration, objc_name="countByEnumerating") FastEnumeration_countByEnumerating :: proc(self: ^FastEnumeration, state: ^FastEnumerationState, buffer: [^]^Object, len: UInteger) -> UInteger { return msgSend(UInteger, self, "countByEnumeratingWithState:objects:count:", state, buffer, len) } @@ -26,7 +39,7 @@ Enumerator_nextObject :: proc(self: ^$E/Enumerator($T)) -> T { return msgSend(T, self, "nextObject") } -Enumerator_allObjects :: proc(self: ^$E/Enumerator($T)) -> (all: Array(T)) { +Enumerator_allObjects :: proc(self: ^$E/Enumerator($T)) -> (all: ^Array) { return msgSend(type_of(all), self, "allObjects") } diff --git a/core/sys/darwin/Foundation/NSError.odin b/core/sys/darwin/Foundation/NSError.odin index aebf01035..bff0088e9 100644 --- a/core/sys/darwin/Foundation/NSError.odin +++ b/core/sys/darwin/Foundation/NSError.odin @@ -31,38 +31,58 @@ foreign Foundation { @(objc_class="NSError") Error :: struct { using _: Copying(Error) } + +@(objc_type=Error, objc_class_name="alloc") +Error_alloc :: proc() -> ^Error { + return msgSend(^Error, Error, "alloc") +} + +@(objc_type=Error, objc_name="init") +Error_init :: proc(self: ^Error) -> ^Error { + return msgSend(^Error, self, "init") +} + +@(objc_type=Error, objc_class_name="errorWithDomain") Error_errorWithDomain :: proc(domain: ErrorDomain, code: Integer, userInfo: ^Dictionary) -> ^Error { return msgSend(^Error, Error, "errorWithDomain:code:userInfo:", domain, code, userInfo) } +@(objc_type=Error, objc_name="initWithDomain") Error_initWithDomain :: proc(self: ^Error, domain: ErrorDomain, code: Integer, userInfo: ^Dictionary) -> ^Error { return msgSend(^Error, self, "initWithDomain:code:userInfo:", domain, code, userInfo) } +@(objc_type=Error, objc_name="code") Error_code :: proc(self: ^Error) -> Integer { return msgSend(Integer, self, "code") } +@(objc_type=Error, objc_name="domain") Error_domain :: proc(self: ^Error) -> ErrorDomain { return msgSend(ErrorDomain, self, "domain") } +@(objc_type=Error, objc_name="userInfo") Error_userInfo :: proc(self: ^Error) -> ^Dictionary { return msgSend(^Dictionary, self, "userInfo") } +@(objc_type=Error, objc_name="localizedDescription") Error_localizedDescription :: proc(self: ^Error) -> ^String { return msgSend(^String, self, "localizedDescription") } -Error_localizedRecoveryOptions :: proc(self: ^Error) -> (options: ^Array(^Object)) { +@(objc_type=Error, objc_name="localizedRecoveryOptions") +Error_localizedRecoveryOptions :: proc(self: ^Error) -> (options: ^Array) { return msgSend(type_of(options), self, "localizedRecoveryOptions") } +@(objc_type=Error, objc_name="localizedRecoverySuggestion") Error_localizedRecoverySuggestion :: proc(self: ^Error) -> ^String { return msgSend(^String, self, "localizedRecoverySuggestion") } +@(objc_type=Error, objc_name="localizedFailureReason") Error_localizedFailureReason :: proc(self: ^Error) -> ^String { return msgSend(^String, self, "localizedFailureReason") } \ No newline at end of file diff --git a/core/sys/darwin/Foundation/NSLock.odin b/core/sys/darwin/Foundation/NSLock.odin index 0e76dfc62..3bcc06eab 100644 --- a/core/sys/darwin/Foundation/NSLock.odin +++ b/core/sys/darwin/Foundation/NSLock.odin @@ -12,18 +12,42 @@ Locking_unlock :: proc(self: ^Locking($T)) { @(objc_class="NSCondition") Condition :: struct {using _: Locking(Condition) } + +@(objc_type=Condition, objc_class_name="alloc") +Condition_alloc :: proc() -> ^Condition { + return msgSend(^Condition, Condition, "alloc") +} + +@(objc_type=Condition, objc_name="init") +Condition_init :: proc(self: ^Condition) -> ^Condition { + return msgSend(^Condition, self, "init") +} + +@(objc_type=Condition, objc_name="wait") Condition_wait :: proc(self: ^Condition) { msgSend(nil, self, "wait") } +@(objc_type=Condition, objc_name="waitUntilDate") Condition_waitUntilDate :: proc(self: ^Condition, limit: ^Date) -> BOOL { return msgSend(BOOL, self, "waitUntilDate:", limit) } +@(objc_type=Condition, objc_name="signal") Condition_signal :: proc(self: ^Condition) { msgSend(nil, self, "signal") } +@(objc_type=Condition, objc_name="broadcast") Condition_broadcast :: proc(self: ^Condition) { msgSend(nil, self, "broadcast") +} + +@(objc_type=Condition, objc_name="lock") +Condition_lock :: proc(self: ^Condition) { + msgSend(nil, self, "lock") +} +@(objc_type=Condition, objc_name="unlock") +Condition_unlock :: proc(self: ^Condition) { + msgSend(nil, self, "unlock") } \ No newline at end of file diff --git a/core/sys/darwin/Foundation/NSNotification.odin b/core/sys/darwin/Foundation/NSNotification.odin index fa9160cc8..d8b142e53 100644 --- a/core/sys/darwin/Foundation/NSNotification.odin +++ b/core/sys/darwin/Foundation/NSNotification.odin @@ -3,14 +3,29 @@ package objc_Foundation @(objc_class="NSNotification") Notification :: struct{using _: Object} + +@(objc_type=Notification, objc_class_name="alloc") +Notification_alloc :: proc() -> ^Notification { + return msgSend(^Notification, Notification, "alloc") +} + +@(objc_type=Notification, objc_name="init") +Notification_init :: proc(self: ^Notification) -> ^Notification { + return msgSend(^Notification, self, "init") +} + + +@(objc_type=Notification, objc_name="name") Notification_name :: proc(self: ^Notification) -> ^String { return msgSend(^String, self, "name") } +@(objc_type=Notification, objc_name="object") Notification_object :: proc(self: ^Notification) -> ^Object { return msgSend(^Object, self, "object") } +@(objc_type=Notification, objc_name="userInfo") Notification_userInfo :: proc(self: ^Notification) -> ^Dictionary { return msgSend(^Dictionary, self, "userInfo") } \ No newline at end of file diff --git a/core/sys/darwin/Foundation/NSNumber.odin b/core/sys/darwin/Foundation/NSNumber.odin index 2630e6daa..f77b0866a 100644 --- a/core/sys/darwin/Foundation/NSNumber.odin +++ b/core/sys/darwin/Foundation/NSNumber.odin @@ -8,35 +8,53 @@ import "core:c" @(objc_class="NSValue") Value :: struct{using _: Copying(Value)} +@(objc_type=Value, objc_class_name="alloc") +Value_alloc :: proc() -> ^Value { + return msgSend(^Value, Value, "alloc") +} + +@(objc_type=Value, objc_name="init") +Value_init :: proc(self: ^Value) -> ^Value { + return msgSend(^Value, self, "init") +} + +@(objc_type=Value, objc_class_name="valueWithBytes") Value_valueWithBytes :: proc(value: rawptr, type: cstring) -> ^Value { return msgSend(^Value, Value, "valueWithBytes:objCType:", value, type) } +@(objc_type=Value, objc_class_name="valueWithPointer") Value_valueWithPointer :: proc(pointer: rawptr) -> ^Value { return msgSend(^Value, Value, "valueWithPointer:", pointer) } +@(objc_type=Value, objc_name="initWithBytes") Value_initWithBytes :: proc(self: ^Value, value: rawptr, type: cstring) -> ^Value { return msgSend(^Value, self, "initWithBytes:objCType:", value, type) } -Value_initWithCoder :: proc(coder: ^Coder) -> ^Value { - return msgSend(^Value, Value, "initWithCoder:", coder) +@(objc_type=Value, objc_name="initWithCoder") +Value_initWithCoder :: proc(self: ^Value, coder: ^Coder) -> ^Value { + return msgSend(^Value, self, "initWithCoder:", coder) } +@(objc_type=Value, objc_name="getValue") Value_getValue :: proc(self: ^Value, value: rawptr, size: UInteger) { msgSend(nil, self, "getValue:size:", value, size) } +@(objc_type=Value, objc_name="objCType") Value_objCType :: proc(self: ^Value) -> cstring { return msgSend(cstring, self, "objCType") } +@(objc_type=Value, objc_name="isEqualToValue") Value_isEqualToValue :: proc(self, other: ^Value) -> BOOL { return msgSend(BOOL, self, "isEqualToValue:", other) } +@(objc_type=Value, objc_name="pointerValue") Value_pointerValue :: proc(self: ^Value) -> rawptr { return msgSend(rawptr, self, "pointerValue") } @@ -46,19 +64,29 @@ Value_pointerValue :: proc(self: ^Value) -> rawptr { Number :: struct{using _: Copying(Number), using _: Value} -Number_numberWithI8 :: proc(value: i8) -> ^Number { return msgSend(^Number, Number, "numberWithChar:", value) } -Number_numberWithU8 :: proc(value: u8) -> ^Number { return msgSend(^Number, Number, "numberWithUnsignedChar:", value) } -Number_numberWithI16 :: proc(value: i16) -> ^Number { return msgSend(^Number, Number, "numberWithShort:", value) } -Number_numberWithU16 :: proc(value: u16) -> ^Number { return msgSend(^Number, Number, "numberWithUnsignedShort:", value) } -Number_numberWithI32 :: proc(value: i32) -> ^Number { return msgSend(^Number, Number, "numberWithInt:", value) } -Number_numberWithU32 :: proc(value: u32) -> ^Number { return msgSend(^Number, Number, "numberWithUnsignedInt:", value) } -Number_numberWithInt :: proc(value: int) -> ^Number { return msgSend(^Number, Number, "numberWithLong:", value) } -Number_numberWithUint :: proc(value: uint) -> ^Number { return msgSend(^Number, Number, "numberWithUnsignedLong:", value) } -Number_numberWithU64 :: proc(value: u64) -> ^Number { return msgSend(^Number, Number, "numberWithLongLong:", value) } -Number_numberWithI64 :: proc(value: i64) -> ^Number { return msgSend(^Number, Number, "numberWithUnsignedLongLong:", value) } -Number_numberWithF32 :: proc(value: f32) -> ^Number { return msgSend(^Number, Number, "numberWithFloat:", value) } -Number_numberWithF64 :: proc(value: f64) -> ^Number { return msgSend(^Number, Number, "numberWithDouble:", value) } -Number_numberWithBool :: proc(value: BOOL) -> ^Number { return msgSend(^Number, Number, "numberWithBool:", value) } +@(objc_type=Number, objc_class_name="alloc") +Number_alloc :: proc() -> ^Number { + return msgSend(^Number, Number, "alloc") +} + +@(objc_type=Number, objc_name="init") +Number_init :: proc(self: ^Number) -> ^Number { + return msgSend(^Number, self, "init") +} + +@(objc_type=Number, objc_class_name="numberWithI8") Number_numberWithI8 :: proc(value: i8) -> ^Number { return msgSend(^Number, Number, "numberWithChar:", value) } +@(objc_type=Number, objc_class_name="numberWithU8") Number_numberWithU8 :: proc(value: u8) -> ^Number { return msgSend(^Number, Number, "numberWithUnsignedChar:", value) } +@(objc_type=Number, objc_class_name="numberWithI16") Number_numberWithI16 :: proc(value: i16) -> ^Number { return msgSend(^Number, Number, "numberWithShort:", value) } +@(objc_type=Number, objc_class_name="numberWithU16") Number_numberWithU16 :: proc(value: u16) -> ^Number { return msgSend(^Number, Number, "numberWithUnsignedShort:", value) } +@(objc_type=Number, objc_class_name="numberWithI32") Number_numberWithI32 :: proc(value: i32) -> ^Number { return msgSend(^Number, Number, "numberWithInt:", value) } +@(objc_type=Number, objc_class_name="numberWithU32") Number_numberWithU32 :: proc(value: u32) -> ^Number { return msgSend(^Number, Number, "numberWithUnsignedInt:", value) } +@(objc_type=Number, objc_class_name="numberWithInt") Number_numberWithInt :: proc(value: int) -> ^Number { return msgSend(^Number, Number, "numberWithLong:", value) } +@(objc_type=Number, objc_class_name="numberWithUint") Number_numberWithUint :: proc(value: uint) -> ^Number { return msgSend(^Number, Number, "numberWithUnsignedLong:", value) } +@(objc_type=Number, objc_class_name="numberWithU64") Number_numberWithU64 :: proc(value: u64) -> ^Number { return msgSend(^Number, Number, "numberWithLongLong:", value) } +@(objc_type=Number, objc_class_name="numberWithI64") Number_numberWithI64 :: proc(value: i64) -> ^Number { return msgSend(^Number, Number, "numberWithUnsignedLongLong:", value) } +@(objc_type=Number, objc_class_name="numberWithF32") Number_numberWithF32 :: proc(value: f32) -> ^Number { return msgSend(^Number, Number, "numberWithFloat:", value) } +@(objc_type=Number, objc_class_name="numberWithF64") Number_numberWithF64 :: proc(value: f64) -> ^Number { return msgSend(^Number, Number, "numberWithDouble:", value) } +@(objc_type=Number, objc_class_name="numberWithBool") Number_numberWithBool :: proc(value: BOOL) -> ^Number { return msgSend(^Number, Number, "numberWithBool:", value) } Number_number :: proc{ Number_numberWithI8, @@ -76,62 +104,49 @@ Number_number :: proc{ Number_numberWithBool, } -Number_initWithI8 :: proc(self: ^Number, value: i8) -> ^Number { return msgSend(^Number, self, "initWithChar:", value) } -Number_initWithU8 :: proc(self: ^Number, value: u8) -> ^Number { return msgSend(^Number, self, "initWithUnsignedChar:", value) } -Number_initWithI16 :: proc(self: ^Number, value: i16) -> ^Number { return msgSend(^Number, self, "initWithShort:", value) } -Number_initWithU16 :: proc(self: ^Number, value: u16) -> ^Number { return msgSend(^Number, self, "initWithUnsignedShort:", value) } -Number_initWithI32 :: proc(self: ^Number, value: i32) -> ^Number { return msgSend(^Number, self, "initWithInt:", value) } -Number_initWithU32 :: proc(self: ^Number, value: u32) -> ^Number { return msgSend(^Number, self, "initWithUnsignedInt:", value) } -Number_initWithInt :: proc(self: ^Number, value: int) -> ^Number { return msgSend(^Number, self, "initWithLong:", value) } -Number_initWithUint :: proc(self: ^Number, value: uint) -> ^Number { return msgSend(^Number, self, "initWithUnsignedLong:", value) } -Number_initWithU64 :: proc(self: ^Number, value: u64) -> ^Number { return msgSend(^Number, self, "initWithLongLong:", value) } -Number_initWithI64 :: proc(self: ^Number, value: i64) -> ^Number { return msgSend(^Number, self, "initWithUnsignedLongLong:", value) } -Number_initWithF32 :: proc(self: ^Number, value: f32) -> ^Number { return msgSend(^Number, self, "initWithFloat:", value) } -Number_initWithF64 :: proc(self: ^Number, value: f64) -> ^Number { return msgSend(^Number, self, "initWithDouble:", value) } -Number_initWithBool :: proc(self: ^Number, value: BOOL) -> ^Number { return msgSend(^Number, self, "initWithBool:", value) } - - -Number_init :: proc{ - Number_initWithI8, - Number_initWithU8, - Number_initWithI16, - Number_initWithU16, - Number_initWithI32, - Number_initWithU32, - Number_initWithInt, - Number_initWithUint, - Number_initWithU64, - Number_initWithI64, - Number_initWithF32, - Number_initWithF64, - Number_initWithBool, -} - -Number_i8Value :: proc(self: ^Number) -> i8 { return msgSend(i8, self, "charValue") } -Number_u8Value :: proc(self: ^Number) -> u8 { return msgSend(u8, self, "unsignedCharValue") } -Number_i16Value :: proc(self: ^Number) -> i16 { return msgSend(i16, self, "shortValue") } -Number_u16Value :: proc(self: ^Number) -> u16 { return msgSend(u16, self, "unsignedShortValue") } -Number_i32Value :: proc(self: ^Number) -> i32 { return msgSend(i32, self, "intValue") } -Number_u32Value :: proc(self: ^Number) -> u32 { return msgSend(u32, self, "unsignedIntValue") } -Number_intValue :: proc(self: ^Number) -> int { return msgSend(int, self, "longValue") } -Number_uintValue :: proc(self: ^Number) -> uint { return msgSend(uint, self, "unsignedLongValue") } -Number_u64Value :: proc(self: ^Number) -> u64 { return msgSend(u64, self, "longLongValue") } -Number_i64Value :: proc(self: ^Number) -> i64 { return msgSend(i64, self, "unsignedLongLongValue") } -Number_f32Value :: proc(self: ^Number) -> f32 { return msgSend(f32, self, "floatValue") } -Number_f64Value :: proc(self: ^Number) -> f64 { return msgSend(f64, self, "doubleValue") } -Number_boolValue :: proc(self: ^Number) -> BOOL { return msgSend(BOOL, self, "boolValue") } -Number_integerValue :: proc(self: ^Number) -> Integer { return msgSend(Integer, self, "integerValue") } -Number_uintegerValue :: proc(self: ^Number) -> UInteger { return msgSend(UInteger, self, "unsignedIntegerValue") } -Number_stringValue :: proc(self: ^Number) -> ^String { return msgSend(^String, self, "stringValue") } - -Number_compare :: proc(a, b: ^Number) -> ComparisonResult { - return msgSend(ComparisonResult, a, "compare:", b) +@(objc_type=Number, objc_name="initWithI8") Number_initWithI8 :: proc(self: ^Number, value: i8) -> ^Number { return msgSend(^Number, self, "initWithChar:", value) } +@(objc_type=Number, objc_name="initWithU8") Number_initWithU8 :: proc(self: ^Number, value: u8) -> ^Number { return msgSend(^Number, self, "initWithUnsignedChar:", value) } +@(objc_type=Number, objc_name="initWithI16") Number_initWithI16 :: proc(self: ^Number, value: i16) -> ^Number { return msgSend(^Number, self, "initWithShort:", value) } +@(objc_type=Number, objc_name="initWithU16") Number_initWithU16 :: proc(self: ^Number, value: u16) -> ^Number { return msgSend(^Number, self, "initWithUnsignedShort:", value) } +@(objc_type=Number, objc_name="initWithI32") Number_initWithI32 :: proc(self: ^Number, value: i32) -> ^Number { return msgSend(^Number, self, "initWithInt:", value) } +@(objc_type=Number, objc_name="initWithU32") Number_initWithU32 :: proc(self: ^Number, value: u32) -> ^Number { return msgSend(^Number, self, "initWithUnsignedInt:", value) } +@(objc_type=Number, objc_name="initWithInt") Number_initWithInt :: proc(self: ^Number, value: int) -> ^Number { return msgSend(^Number, self, "initWithLong:", value) } +@(objc_type=Number, objc_name="initWithUint") Number_initWithUint :: proc(self: ^Number, value: uint) -> ^Number { return msgSend(^Number, self, "initWithUnsignedLong:", value) } +@(objc_type=Number, objc_name="initWithU64") Number_initWithU64 :: proc(self: ^Number, value: u64) -> ^Number { return msgSend(^Number, self, "initWithLongLong:", value) } +@(objc_type=Number, objc_name="initWithI64") Number_initWithI64 :: proc(self: ^Number, value: i64) -> ^Number { return msgSend(^Number, self, "initWithUnsignedLongLong:", value) } +@(objc_type=Number, objc_name="initWithF32") Number_initWithF32 :: proc(self: ^Number, value: f32) -> ^Number { return msgSend(^Number, self, "initWithFloat:", value) } +@(objc_type=Number, objc_name="initWithF64") Number_initWithF64 :: proc(self: ^Number, value: f64) -> ^Number { return msgSend(^Number, self, "initWithDouble:", value) } +@(objc_type=Number, objc_name="initWithBool") Number_initWithBool :: proc(self: ^Number, value: BOOL) -> ^Number { return msgSend(^Number, self, "initWithBool:", value) } + + +@(objc_type=Number, objc_name="i8Value") Number_i8Value :: proc(self: ^Number) -> i8 { return msgSend(i8, self, "charValue") } +@(objc_type=Number, objc_name="u8Value") Number_u8Value :: proc(self: ^Number) -> u8 { return msgSend(u8, self, "unsignedCharValue") } +@(objc_type=Number, objc_name="i16Value") Number_i16Value :: proc(self: ^Number) -> i16 { return msgSend(i16, self, "shortValue") } +@(objc_type=Number, objc_name="u16Value") Number_u16Value :: proc(self: ^Number) -> u16 { return msgSend(u16, self, "unsignedShortValue") } +@(objc_type=Number, objc_name="i32Value") Number_i32Value :: proc(self: ^Number) -> i32 { return msgSend(i32, self, "intValue") } +@(objc_type=Number, objc_name="u32Value") Number_u32Value :: proc(self: ^Number) -> u32 { return msgSend(u32, self, "unsignedIntValue") } +@(objc_type=Number, objc_name="intValue") Number_intValue :: proc(self: ^Number) -> int { return msgSend(int, self, "longValue") } +@(objc_type=Number, objc_name="uintValue") Number_uintValue :: proc(self: ^Number) -> uint { return msgSend(uint, self, "unsignedLongValue") } +@(objc_type=Number, objc_name="u64Value") Number_u64Value :: proc(self: ^Number) -> u64 { return msgSend(u64, self, "longLongValue") } +@(objc_type=Number, objc_name="i64Value") Number_i64Value :: proc(self: ^Number) -> i64 { return msgSend(i64, self, "unsignedLongLongValue") } +@(objc_type=Number, objc_name="f32Value") Number_f32Value :: proc(self: ^Number) -> f32 { return msgSend(f32, self, "floatValue") } +@(objc_type=Number, objc_name="f64Value") Number_f64Value :: proc(self: ^Number) -> f64 { return msgSend(f64, self, "doubleValue") } +@(objc_type=Number, objc_name="boolValue") Number_boolValue :: proc(self: ^Number) -> BOOL { return msgSend(BOOL, self, "boolValue") } +@(objc_type=Number, objc_name="integerValue") Number_integerValue :: proc(self: ^Number) -> Integer { return msgSend(Integer, self, "integerValue") } +@(objc_type=Number, objc_name="uintegerValue") Number_uintegerValue :: proc(self: ^Number) -> UInteger { return msgSend(UInteger, self, "unsignedIntegerValue") } +@(objc_type=Number, objc_name="stringValue") Number_stringValue :: proc(self: ^Number) -> ^String { return msgSend(^String, self, "stringValue") } + +@(objc_type=Number, objc_name="compare") +Number_compare :: proc(self, other: ^Number) -> ComparisonResult { + return msgSend(ComparisonResult, self, "compare:", other) } -Number_isEqualToNumber :: proc(a, b: ^Number) -> BOOL { - return msgSend(BOOL, a, "isEqualToNumber:", b) +@(objc_type=Number, objc_name="isEqualToNumber") +Number_isEqualToNumber :: proc(self, other: ^Number) -> BOOL { + return msgSend(BOOL, self, "isEqualToNumber:", other) } +@(objc_type=Number, objc_name="descriptionWithLocale") Number_descriptionWithLocale :: proc(self: ^Number, locale: ^Object) -> ^String { return msgSend(^String, self, "descriptionWithLocale:", locale) } \ No newline at end of file diff --git a/core/sys/darwin/Foundation/NSObject.odin b/core/sys/darwin/Foundation/NSObject.odin index d61f8e947..cd0919edd 100644 --- a/core/sys/darwin/Foundation/NSObject.odin +++ b/core/sys/darwin/Foundation/NSObject.odin @@ -27,37 +27,45 @@ alloc :: proc($T: typeid) -> ^T where intrinsics.type_is_subtype_of(T, Object) { init :: proc(self: ^$T) -> ^T where intrinsics.type_is_subtype_of(T, Object) { return msgSend(^T, self, "init") } -retain :: proc(self: ^$T) -> ^T where intrinsics.type_is_subtype_of(T, Object) { - return msgSend(^T, self, "retain") +copy :: proc(self: ^Copying($T)) -> ^T where intrinsics.type_is_subtype_of(T, Object) { + return msgSend(^T, self, "copy") +} + + +@(objc_type=Object, objc_name="retain") +retain :: proc(self: ^Object) { + _ = msgSend(^Object, self, "retain") } -release :: proc(self: ^$T) where intrinsics.type_is_subtype_of(T, Object) { +@(objc_type=Object, objc_name="release") +release :: proc(self: ^Object) { msgSend(nil, self, "release") } -autorelease :: proc(self: ^$T) where intrinsics.type_is_subtype_of(T, Object) { +@(objc_type=Object, objc_name="autorelease") +autorelease :: proc(self: ^Object) { msgSend(nil, self, "autorelease") } -retainCount :: proc(self: ^$T) -> UInteger where intrinsics.type_is_subtype_of(T, Object) { +@(objc_type=Object, objc_name="retainCount") +retainCount :: proc(self: ^Object) -> UInteger { return msgSend(UInteger, self, "retainCount") } -copy :: proc(self: ^Copying($T)) -> ^T where intrinsics.type_is_subtype_of(T, Object) { - return msgSend(^T, self, "copy") -} - - +@(objc_type=Object, objc_name="hash") hash :: proc(self: ^Object) -> UInteger { return msgSend(UInteger, self, "hash") } +@(objc_type=Object, objc_name="isEqual") isEqual :: proc(self, pObject: ^Object) -> BOOL { return msgSend(BOOL, self, "isEqual:", pObject) } +@(objc_type=Object, objc_name="description") description :: proc(self: ^Object) -> ^String { return msgSend(^String, self, "description") } +@(objc_type=Object, objc_name="debugDescription") debugDescription :: proc(self: ^Object) -> ^String { if msgSendSafeCheck(self, intrinsics.objc_selector_name("debugDescription")) { return msgSend(^String, self, "debugDescription") diff --git a/core/sys/darwin/Foundation/NSString.odin b/core/sys/darwin/Foundation/NSString.odin index 86c8cabea..06dbc27a3 100644 --- a/core/sys/darwin/Foundation/NSString.odin +++ b/core/sys/darwin/Foundation/NSString.odin @@ -59,54 +59,78 @@ MakeConstantString :: proc "c" (#const c: cstring) -> ^String { } +@(objc_type=String, objc_class_name="alloc") +String_alloc :: proc() -> ^String { + return msgSend(^String, String, "alloc") +} + +@(objc_type=String, objc_name="init") +String_init :: proc(self: ^String) -> ^String { + return msgSend(^String, self, "init") +} + + +@(objc_type=String, objc_name="initWithString") String_initWithString :: proc(self: ^String, other: ^String) -> ^String { return msgSend(^String, self, "initWithString:", other) } +@(objc_type=String, objc_name="initWithCString") String_initWithCString :: proc(self: ^String, pString: cstring, encoding: StringEncoding) -> ^String { return msgSend(^String, self, "initWithCstring:encoding:", pString, encoding) } +@(objc_type=String, objc_name="initWithBytesNoCopy") String_initWithBytesNoCopy :: proc(self: ^String, pBytes: rawptr, length: UInteger, encoding: StringEncoding, freeWhenDone: bool) -> ^String { return msgSend(^String, self, "initWithBytesNoCopy:length:encoding:freeWhenDone:", pBytes, length, encoding, freeWhenDone) } +@(objc_type=String, objc_name="initWithOdinString") String_initWithOdinString :: proc(self: ^String, str: string) -> ^String { return String_initWithBytesNoCopy(self, raw_data(str), UInteger(len(str)), .UTF8, false) } +@(objc_type=String, objc_name="characterAtIndex") String_characterAtIndex :: proc(self: ^String, index: UInteger) -> unichar { return msgSend(unichar, self, "characterAtIndex:", index) } +@(objc_type=String, objc_name="length") String_length :: proc(self: ^String) -> UInteger { return msgSend(UInteger, self, "length") } +@(objc_type=String, objc_name="cStringUsingEncoding") String_cStringUsingEncoding :: proc(self: ^String, encoding: StringEncoding) -> cstring { return msgSend(cstring, self, "cStringUsingEncoding:", encoding) } +@(objc_type=String, objc_name="UTF8String") String_UTF8String :: proc(self: ^String) -> cstring { return msgSend(cstring, self, "UTF8String") } +@(objc_type=String, objc_name="OdinString") String_OdinString :: proc(self: ^String) -> string { return string(String_UTF8String(self)) } +@(objc_type=String, objc_name="maximumLengthOfBytesUsingEncoding") String_maximumLengthOfBytesUsingEncoding :: proc(self: ^String, encoding: StringEncoding) -> UInteger { return msgSend(UInteger, self, "maximumLengthOfBytesUsingEncoding:", encoding) } +@(objc_type=String, objc_name="lengthOfBytesUsingEncoding") String_lengthOfBytesUsingEncoding :: proc(self: ^String, encoding: StringEncoding) -> UInteger { return msgSend(UInteger, self, "lengthOfBytesUsingEncoding:", encoding) } +@(objc_type=String, objc_name="isEqualToString") String_isEqualToString :: proc(self, other: ^String) -> BOOL { return msgSend(BOOL, self, "isEqualToString:", other) } +@(objc_type=String, objc_name="rangeOfString") String_rangeOfString :: proc(self, other: ^String, options: StringCompareOptions) -> Range { return msgSend(Range, self, "rangeOfString:options:", other, options) } \ No newline at end of file diff --git a/core/sys/darwin/Foundation/NSURL.odin b/core/sys/darwin/Foundation/NSURL.odin index f4f776130..42edf91c0 100644 --- a/core/sys/darwin/Foundation/NSURL.odin +++ b/core/sys/darwin/Foundation/NSURL.odin @@ -3,6 +3,18 @@ package objc_Foundation @(objc_class="NSURL") URL :: struct{using _: Copying(URL)} + +@(objc_type=URL, objc_class_name="alloc") +URL_alloc :: proc() -> ^URL { + return msgSend(^URL, URL, "alloc") +} + +@(objc_type=URL, objc_name="init") +URL_init :: proc(self: ^URL) -> ^URL { + return msgSend(^URL, self, "init") +} + + URL_initWithString :: proc(self: ^URL, value: ^String) -> ^URL { return msgSend(^URL, self, "initWithString:", value) } diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index df22d82e2..a9ee5d25f 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -287,15 +287,13 @@ bool check_builtin_objc_procedure(CheckerContext *c, Operand *operand, Ast *call Operand self = {}; check_expr_or_type(c, &self, ce->args[1]); if (self.mode == Addressing_Type) { - if (!internal_check_is_assignable_to(self.type, t_objc_object)) { + if (!is_type_objc_object(self.type)) { gbString t = type_to_string(self.type); error(self.expr, "'%.*s' expected a type or value derived from intrinsics.objc_object, got type %s", LIT(builtin_name), t); gb_string_free(t); return false; } - if (!(self.type->kind == Type_Named && - self.type->Named.type_name != nullptr && - self.type->Named.type_name->TypeName.objc_class_name != "")) { + if (!has_type_got_objc_class_attribute(self.type)) { gbString t = type_to_string(self.type); error(self.expr, "'%.*s' expected a named type with the attribute @(obj_class=) , got type %s", LIT(builtin_name), t); gb_string_free(t); @@ -306,7 +304,7 @@ bool check_builtin_objc_procedure(CheckerContext *c, Operand *operand, Ast *call } else if (!is_operand_value(self) || !check_is_assignable_to(c, &self, t_objc_id)) { gbString e = expr_to_string(self.expr); gbString t = type_to_string(self.type); - error(self.expr, "'%.*s'3 expected a type or value derived from intrinsics.objc_object, got '%s' of type %s %d", LIT(builtin_name), e, t, self.type->kind); + error(self.expr, "'%.*s' expected a type or value derived from intrinsics.objc_object, got '%s' of type %s %d", LIT(builtin_name), e, t, self.type->kind); gb_string_free(t); gb_string_free(e); return false; diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 243dbbbc6..1d30088d6 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -340,6 +340,10 @@ void check_type_decl(CheckerContext *ctx, Entity *e, Ast *init_expr, Type *def) check_decl_attributes(ctx, decl->attributes, type_decl_attribute, &ac); if (e->kind == Entity_TypeName && ac.objc_class != "") { e->TypeName.objc_class_name = ac.objc_class; + + if (type_size_of(e->type) > 0) { + error(e->token, "@(objc_class) marked type must be of zero size"); + } } } @@ -822,6 +826,65 @@ void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) { } e->Procedure.optimization_mode = cast(ProcedureOptimizationMode)ac.optimization_mode; + if (ac.objc_name.len || ac.objc_class_name.len || ac.objc_type) { + if (ac.objc_class_name.len && ac.objc_name.len) { + error(e->token, "@(objc_class_name) and @(objc_name) may not be allowed at the same time"); + } else if (ac.objc_type == nullptr) { + if (ac.objc_name.len) { + error(e->token, "@(objc_name) requires that @(objc_type) to be set"); + } else { + error(e->token, "@(objc_class_name) requires that @(objc_type) to be set"); + } + } else { + Type *t = ac.objc_type; + if (t->kind == Type_Named) { + Entity *tn = t->Named.type_name; + + GB_ASSERT(tn->kind == Entity_TypeName); + + if (tn->scope != e->scope) { + error(e->token, "@(objc_name) and @(objc_class_name) attributes may only be applied to procedures and types within the same scope"); + } else { + mutex_lock(&global_type_name_objc_metadata_mutex); + defer (mutex_unlock(&global_type_name_objc_metadata_mutex)); + + if (!tn->TypeName.objc_metadata) { + tn->TypeName.objc_metadata = create_type_name_obj_c_metadata(); + } + auto *md = tn->TypeName.objc_metadata; + mutex_lock(md->mutex); + defer (mutex_unlock(md->mutex)); + + if (ac.objc_name.len) { + bool ok = true; + for (TypeNameObjCMetadataEntry const &entry : md->value_entries) { + if (entry.name == ac.objc_name) { + error(e->token, "Previous declaration of @(objc_name=\"%.*s\")", LIT(ac.objc_name)); + ok = false; + break; + } + } + if (ok) { + array_add(&md->value_entries, TypeNameObjCMetadataEntry{ac.objc_name, e}); + } + } else { + bool ok = true; + for (TypeNameObjCMetadataEntry const &entry : md->type_entries) { + if (entry.name == ac.objc_class_name) { + error(e->token, "Previous declaration of @(objc_class_name=\"%.*s\")", LIT(ac.objc_class_name)); + ok = false; + break; + } + } + if (ok) { + array_add(&md->type_entries, TypeNameObjCMetadataEntry{ac.objc_class_name, e}); + } + } + } + } + } + } + switch (e->Procedure.optimization_mode) { case ProcedureOptimizationMode_None: diff --git a/src/check_type.cpp b/src/check_type.cpp index e1a0df7e6..32340070e 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -325,6 +325,8 @@ void add_polymorphic_record_entity(CheckerContext *ctx, Ast *node, Type *named_t named_type->Named.type_name = e; GB_ASSERT(original_type->kind == Type_Named); e->TypeName.objc_class_name = original_type->Named.type_name->TypeName.objc_class_name; + // TODO(bill): Is this even correct? Or should the metadata be copied? + e->TypeName.objc_metadata = original_type->Named.type_name->TypeName.objc_metadata; mutex_lock(&ctx->info->gen_types_mutex); auto *found_gen_types = map_get(&ctx->info->gen_types, original_type); diff --git a/src/checker.cpp b/src/checker.cpp index 2ab487592..0dd36987e 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -4,7 +4,7 @@ void check_expr(CheckerContext *c, Operand *operand, Ast *expression); void check_expr_or_type(CheckerContext *c, Operand *operand, Ast *expression, Type *type_hint=nullptr); void add_comparison_procedures_for_fields(CheckerContext *c, Type *t); - +Type *check_type(CheckerContext *ctx, Ast *e); bool is_operand_value(Operand o) { switch (o.mode) { @@ -2740,6 +2740,14 @@ ExactValue check_decl_attribute_value(CheckerContext *c, Ast *value) { return ev; } +Type *check_decl_attribute_type(CheckerContext *c, Ast *value) { + if (value != nullptr) { + return check_type(c, value); + } + return nullptr; +} + + #define ATTRIBUTE_USER_TAG_NAME "tag" @@ -3039,6 +3047,46 @@ DECL_ATTRIBUTE_PROC(proc_decl_attribute) { error(elem, "Expected a string for '%.*s'", LIT(name)); } return true; + } else if (name == "objc_name") { + ExactValue ev = check_decl_attribute_value(c, value); + if (ev.kind == ExactValue_String) { + if (string_is_valid_identifier(ev.value_string)) { + ac->objc_name = ev.value_string; + } else { + error(elem, "Invalid identifier for '%.*s', got '%.*s'", LIT(name), LIT(ev.value_string)); + } + } else { + error(elem, "Expected a string value for '%.*s'", LIT(name)); + } + return true; + } else if (name == "objc_class_name") { + ExactValue ev = check_decl_attribute_value(c, value); + if (ev.kind == ExactValue_String) { + if (string_is_valid_identifier(ev.value_string)) { + ac->objc_class_name = ev.value_string; + } else { + error(elem, "Invalid identifier for '%.*s', got '%.*s'", LIT(name), LIT(ev.value_string)); + } + } else { + error(elem, "Expected a string value for '%.*s'", LIT(name)); + } + return true; + } else if (name == "objc_type") { + if (value == nullptr) { + error(elem, "Expected a type for '%.*s'", LIT(name)); + } else { + Type *objc_type = check_type(c, value); + if (objc_type != nullptr) { + if (!has_type_got_objc_class_attribute(objc_type)) { + gbString t = type_to_string(objc_type); + error(value, "'%.*s' expected a named type with the attribute @(obj_class=), got type %s", LIT(name), t); + gb_string_free(t); + } else { + ac->objc_type = objc_type; + } + } + } + return true; } return false; } diff --git a/src/checker.hpp b/src/checker.hpp index b812e10a4..38c8d32f6 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -107,7 +107,6 @@ struct AttributeContext { String thread_local_model; String deprecated_message; String warning_message; - String objc_class; DeferredProcedure deferred_procedure; bool is_export : 1; bool is_static : 1; @@ -119,6 +118,11 @@ struct AttributeContext { bool init : 1; bool set_cold : 1; u32 optimization_mode; // ProcedureOptimizationMode + + String objc_class; + String objc_name; + String objc_class_name; + Type * objc_type; }; AttributeContext make_attribute_context(String link_prefix) { diff --git a/src/entity.cpp b/src/entity.cpp index 4d5b3b9e1..df8ee3faa 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -122,6 +122,28 @@ enum ProcedureOptimizationMode : u32 { ProcedureOptimizationMode_Speed, }; + +BlockingMutex global_type_name_objc_metadata_mutex; + +struct TypeNameObjCMetadataEntry { + String name; + Entity *entity; +}; +struct TypeNameObjCMetadata { + BlockingMutex *mutex; + Array type_entries; + Array value_entries; +}; + +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); + array_init(&md->type_entries, heap_allocator()); + array_init(&md->value_entries, heap_allocator()); + return md; +} + // An Entity is a named "thing" in the language struct Entity { EntityKind kind; @@ -187,6 +209,7 @@ struct Entity { String ir_mangled_name; bool is_type_alias; String objc_class_name; + TypeNameObjCMetadata *objc_metadata; } TypeName; struct { u64 tags; diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp index 29a86d116..b2f430cd2 100644 --- a/src/llvm_backend_expr.cpp +++ b/src/llvm_backend_expr.cpp @@ -3320,7 +3320,12 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) { Type *type = base_type(tav.type); if (tav.mode == Addressing_Type) { // Addressing_Type - GB_PANIC("Unreachable"); + Selection sel = lookup_field(tav.type, selector, true); + if (sel.pseudo_field) { + GB_ASSERT(sel.entity->kind == Entity_Procedure); + return lb_addr(lb_find_value_from_entity(p->module, sel.entity)); + } + GB_PANIC("Unreachable %.*s", LIT(selector)); } if (se->swizzle_count > 0) { @@ -3347,6 +3352,10 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) { Selection sel = lookup_field(type, selector, false); GB_ASSERT(sel.entity != nullptr); + if (sel.pseudo_field) { + GB_ASSERT(sel.entity->kind == Entity_Procedure); + return lb_addr(lb_find_value_from_entity(p->module, sel.entity)); + } { lbAddr addr = lb_build_addr(p, se->expr); diff --git a/src/main.cpp b/src/main.cpp index fe56d451f..bd06193bd 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -585,37 +585,6 @@ void usage(String argv0) { print_usage_line(1, "e.g. odin build -help"); } - -bool string_is_valid_identifier(String str) { - if (str.len <= 0) return false; - - isize rune_count = 0; - - isize w = 0; - isize offset = 0; - while (offset < str.len) { - Rune r = 0; - w = utf8_decode(str.text, str.len, &r); - if (r == GB_RUNE_INVALID) { - return false; - } - - if (rune_count == 0) { - if (!rune_is_letter(r)) { - return false; - } - } else { - if (!rune_is_letter(r) && !rune_is_digit(r)) { - return false; - } - } - rune_count += 1; - offset += w; - } - - return true; -} - enum BuildFlagKind { BuildFlag_Invalid, @@ -2447,6 +2416,7 @@ int main(int arg_count, char const **arg_ptr) { virtual_memory_init(); mutex_init(&fullpath_mutex); mutex_init(&hash_exact_value_mutex); + mutex_init(&global_type_name_objc_metadata_mutex); init_string_buffer_memory(); init_string_interner(); diff --git a/src/string.cpp b/src/string.cpp index eb6058f78..bcaf23b9b 100644 --- a/src/string.cpp +++ b/src/string.cpp @@ -781,3 +781,34 @@ i32 unquote_string(gbAllocator a, String *s_, u8 quote=0, bool has_carriage_retu return 2; } + + +bool string_is_valid_identifier(String str) { + if (str.len <= 0) return false; + + isize rune_count = 0; + + isize w = 0; + isize offset = 0; + while (offset < str.len) { + Rune r = 0; + w = utf8_decode(str.text, str.len, &r); + if (r == GB_RUNE_INVALID) { + return false; + } + + if (rune_count == 0) { + if (!rune_is_letter(r)) { + return false; + } + } else { + if (!rune_is_letter(r) && !rune_is_digit(r)) { + return false; + } + } + rune_count += 1; + offset += w; + } + + return true; +} diff --git a/src/types.cpp b/src/types.cpp index 024d644a2..78958146b 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -393,6 +393,7 @@ struct Selection { bool indirect; // Set if there was a pointer deref anywhere down the line u8 swizzle_count; // maximum components = 4 u8 swizzle_indices; // 2 bits per component, representing which swizzle index + bool pseudo_field; }; Selection empty_selection = {0}; @@ -2782,6 +2783,7 @@ Selection lookup_field_from_index(Type *type, i64 index) { } Entity *scope_lookup_current(Scope *s, String const &name); +bool has_type_got_objc_class_attribute(Type *t); Selection lookup_field_with_selection(Type *type_, String field_name, bool is_type, Selection sel, bool allow_blank_ident) { GB_ASSERT(type_ != nullptr); @@ -2794,9 +2796,40 @@ Selection lookup_field_with_selection(Type *type_, String field_name, bool is_ty bool is_ptr = type != type_; sel.indirect = sel.indirect || is_ptr; + Type *original_type = type; + type = base_type(type); if (is_type) { + if (has_type_got_objc_class_attribute(original_type) && original_type->kind == Type_Named) { + Entity *e = original_type->Named.type_name; + GB_ASSERT(e->kind == Entity_TypeName); + if (e->TypeName.objc_metadata) { + auto *md = e->TypeName.objc_metadata; + mutex_lock(md->mutex); + defer (mutex_unlock(md->mutex)); + for (TypeNameObjCMetadataEntry const &entry : md->type_entries) { + GB_ASSERT(entry.entity->kind == Entity_Procedure); + if (entry.name == field_name) { + sel.entity = entry.entity; + sel.pseudo_field = true; + return sel; + } + } + } + if (type->kind == Type_Struct) { + for_array(i, type->Struct.fields) { + Entity *f = type->Struct.fields[i]; + if (f->flags&EntityFlag_Using) { + sel = lookup_field_with_selection(f->type, field_name, is_type, sel, allow_blank_ident); + if (sel.entity) { + return sel; + } + } + } + } + } + if (is_type_enum(type)) { // NOTE(bill): These may not have been added yet, so check in case for_array(i, type->Enum.fields) { @@ -2843,6 +2876,24 @@ Selection lookup_field_with_selection(Type *type_, String field_name, bool is_ty } else if (type->kind == Type_Union) { } else if (type->kind == Type_Struct) { + if (has_type_got_objc_class_attribute(original_type) && original_type->kind == Type_Named) { + Entity *e = original_type->Named.type_name; + GB_ASSERT(e->kind == Entity_TypeName); + if (e->TypeName.objc_metadata) { + auto *md = e->TypeName.objc_metadata; + mutex_lock(md->mutex); + defer (mutex_unlock(md->mutex)); + for (TypeNameObjCMetadataEntry const &entry : md->value_entries) { + GB_ASSERT(entry.entity->kind == Entity_Procedure); + if (entry.name == field_name) { + sel.entity = entry.entity; + sel.pseudo_field = true; + return sel; + } + } + } + } + for_array(i, type->Struct.fields) { Entity *f = type->Struct.fields[i]; if (f->kind != Entity_Variable || (f->flags & EntityFlag_Field) == 0) { @@ -3792,6 +3843,17 @@ bool is_type_subtype_of(Type *src, Type *dst) { } +bool has_type_got_objc_class_attribute(Type *t) { + return t->kind == Type_Named && t->Named.type_name != nullptr && t->Named.type_name->TypeName.objc_class_name != ""; +} + + + +bool is_type_objc_object(Type *t) { + bool internal_check_is_assignable_to(Type *src, Type *dst); + + return internal_check_is_assignable_to(t, t_objc_object); +} Type *get_struct_field_type(Type *t, isize index) { t = base_type(type_deref(t)); -- cgit v1.2.3 From 03aec70287714fb9d66864e6db0d9e6375c18362 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 14 Feb 2022 17:31:55 +0000 Subject: Change objc_class_name to objc_name with objc_is_class_method --- core/sys/darwin/Foundation/NSArray.odin | 2 +- core/sys/darwin/Foundation/NSAutoreleasePool.odin | 2 +- core/sys/darwin/Foundation/NSBundle.odin | 8 +- core/sys/darwin/Foundation/NSData.odin | 2 +- core/sys/darwin/Foundation/NSDate.odin | 2 +- core/sys/darwin/Foundation/NSDictionary.odin | 8 +- core/sys/darwin/Foundation/NSEnumerator.odin | 2 +- core/sys/darwin/Foundation/NSError.odin | 4 +- core/sys/darwin/Foundation/NSLock.odin | 2 +- core/sys/darwin/Foundation/NSNotification.odin | 2 +- core/sys/darwin/Foundation/NSNumber.odin | 34 ++-- core/sys/darwin/Foundation/NSString.odin | 2 +- core/sys/darwin/Foundation/NSURL.odin | 2 +- core/sys/darwin/Metal/MetalClasses.odin | 226 +++++++++++----------- core/sys/darwin/QuartzCore/QuartzCore.odin | 2 +- src/check_decl.cpp | 24 ++- src/checker.cpp | 12 +- src/checker.hpp | 2 +- 18 files changed, 166 insertions(+), 172 deletions(-) (limited to 'src/checker.cpp') diff --git a/core/sys/darwin/Foundation/NSArray.odin b/core/sys/darwin/Foundation/NSArray.odin index e17223ff7..d6021838b 100644 --- a/core/sys/darwin/Foundation/NSArray.odin +++ b/core/sys/darwin/Foundation/NSArray.odin @@ -7,7 +7,7 @@ Array :: struct { using _: Copying(Array), } -@(objc_type=Array, objc_class_name="alloc") +@(objc_type=Array, objc_name="alloc", objc_is_class_method=true) Array_alloc :: proc() -> ^Array { return msgSend(^Array, Array, "alloc") } diff --git a/core/sys/darwin/Foundation/NSAutoreleasePool.odin b/core/sys/darwin/Foundation/NSAutoreleasePool.odin index 17ec88ba1..a388a7146 100644 --- a/core/sys/darwin/Foundation/NSAutoreleasePool.odin +++ b/core/sys/darwin/Foundation/NSAutoreleasePool.odin @@ -3,7 +3,7 @@ package objc_Foundation @(objc_class="NSAutoreleasePool") AutoreleasePool :: struct {using _: Object} -@(objc_type=AutoreleasePool, objc_class_name="alloc") +@(objc_type=AutoreleasePool, objc_name="alloc", objc_is_class_method=true) AutoreleasePool_alloc :: proc() -> ^AutoreleasePool { return msgSend(^AutoreleasePool, AutoreleasePool, "alloc") } diff --git a/core/sys/darwin/Foundation/NSBundle.odin b/core/sys/darwin/Foundation/NSBundle.odin index a18809b7e..4f5a8e928 100644 --- a/core/sys/darwin/Foundation/NSBundle.odin +++ b/core/sys/darwin/Foundation/NSBundle.odin @@ -3,23 +3,23 @@ package objc_Foundation @(objc_class="NSBundle") Bundle :: struct { using _: Object } -@(objc_type=Bundle, objc_class_name="mainBundle") +@(objc_type=Bundle, objc_name="mainBundle", objc_is_class_method=true) Bundle_mainBundle :: proc() -> ^Bundle { return msgSend(^Bundle, Bundle, "mainBundle") } -@(objc_type=Bundle, objc_class_name="bundleWithPath") +@(objc_type=Bundle, objc_name="bundleWithPath", objc_is_class_method=true) Bundle_bundleWithPath :: proc(path: ^String) -> ^Bundle { return msgSend(^Bundle, Bundle, "bundleWithPath:", path) } -@(objc_type=Bundle, objc_class_name="bundleWithURL") +@(objc_type=Bundle, objc_name="bundleWithURL", objc_is_class_method=true) Bundle_bundleWithURL :: proc(url: ^URL) -> ^Bundle { return msgSend(^Bundle, Bundle, "bundleWithUrl:", url) } -@(objc_type=Bundle, objc_class_name="alloc") +@(objc_type=Bundle, objc_name="alloc", objc_is_class_method=true) Bundle_alloc :: proc() -> ^Bundle { return msgSend(^Bundle, Bundle, "alloc") } diff --git a/core/sys/darwin/Foundation/NSData.odin b/core/sys/darwin/Foundation/NSData.odin index e28f6a644..3c6369e86 100644 --- a/core/sys/darwin/Foundation/NSData.odin +++ b/core/sys/darwin/Foundation/NSData.odin @@ -3,7 +3,7 @@ package objc_Foundation @(objc_class="NSData") Data :: struct {using _: Copying(Data)} -@(objc_type=Data, objc_class_name="alloc") +@(objc_type=Data, objc_name="alloc", objc_is_class_method=true) Data_alloc :: proc() -> ^Data { return msgSend(^Data, Data, "alloc") } diff --git a/core/sys/darwin/Foundation/NSDate.odin b/core/sys/darwin/Foundation/NSDate.odin index 85bb14c3e..cd63d313a 100644 --- a/core/sys/darwin/Foundation/NSDate.odin +++ b/core/sys/darwin/Foundation/NSDate.odin @@ -3,7 +3,7 @@ package objc_Foundation @(objc_class="NSDate") Date :: struct {using _: Copying(Date)} -@(objc_type=Date, objc_class_name="alloc") +@(objc_type=Date, objc_name="alloc", objc_is_class_method=true) Date_alloc :: proc() -> ^Date { return msgSend(^Date, Date, "alloc") } diff --git a/core/sys/darwin/Foundation/NSDictionary.odin b/core/sys/darwin/Foundation/NSDictionary.odin index 3eb378dc7..1f009841a 100644 --- a/core/sys/darwin/Foundation/NSDictionary.odin +++ b/core/sys/darwin/Foundation/NSDictionary.odin @@ -3,23 +3,23 @@ package objc_Foundation @(objc_class="NSDictionary") Dictionary :: struct {using _: Copying(Dictionary)} -@(objc_type=Dictionary, objc_class_name="dictionary") +@(objc_type=Dictionary, objc_name="dictionary", objc_is_class_method=true) Dictionary_dictionary :: proc() -> ^Dictionary { return msgSend(^Dictionary, Dictionary, "dictionary") } -@(objc_type=Dictionary, objc_class_name="dictionaryWithObject") +@(objc_type=Dictionary, objc_name="dictionaryWithObject", objc_is_class_method=true) Dictionary_dictionaryWithObject :: proc(object: ^Object, forKey: ^Object) -> ^Dictionary { return msgSend(^Dictionary, Dictionary, "dictionaryWithObject:forKey:", object, forKey) } -@(objc_type=Dictionary, objc_class_name="dictionaryWithObjects") +@(objc_type=Dictionary, objc_name="dictionaryWithObjects", objc_is_class_method=true) Dictionary_dictionaryWithObjects :: proc(objects: [^]^Object, forKeys: [^]^Object, count: UInteger) -> ^Dictionary { return msgSend(^Dictionary, Dictionary, "dictionaryWithObjects:forKeys:count", objects, forKeys, count) } -@(objc_type=Dictionary, objc_class_name="alloc") +@(objc_type=Dictionary, objc_name="alloc", objc_is_class_method=true) Dictionary_alloc :: proc() -> ^Dictionary { return msgSend(^Dictionary, Dictionary, "alloc") } diff --git a/core/sys/darwin/Foundation/NSEnumerator.odin b/core/sys/darwin/Foundation/NSEnumerator.odin index 8a5a32e69..1c7ddeed2 100644 --- a/core/sys/darwin/Foundation/NSEnumerator.odin +++ b/core/sys/darwin/Foundation/NSEnumerator.odin @@ -19,7 +19,7 @@ Enumerator :: struct($T: typeid) where intrinsics.type_is_pointer(T), intrinsics } -@(objc_type=FastEnumeration, objc_class_name="alloc") +@(objc_type=FastEnumeration, objc_name="alloc", objc_is_class_method=true) FastEnumeration_alloc :: proc() -> ^FastEnumeration { return msgSend(^FastEnumeration, FastEnumeration, "alloc") } diff --git a/core/sys/darwin/Foundation/NSError.odin b/core/sys/darwin/Foundation/NSError.odin index bff0088e9..23e6eaba7 100644 --- a/core/sys/darwin/Foundation/NSError.odin +++ b/core/sys/darwin/Foundation/NSError.odin @@ -32,7 +32,7 @@ foreign Foundation { Error :: struct { using _: Copying(Error) } -@(objc_type=Error, objc_class_name="alloc") +@(objc_type=Error, objc_name="alloc", objc_is_class_method=true) Error_alloc :: proc() -> ^Error { return msgSend(^Error, Error, "alloc") } @@ -42,7 +42,7 @@ Error_init :: proc(self: ^Error) -> ^Error { return msgSend(^Error, self, "init") } -@(objc_type=Error, objc_class_name="errorWithDomain") +@(objc_type=Error, objc_name="errorWithDomain", objc_is_class_method=true) Error_errorWithDomain :: proc(domain: ErrorDomain, code: Integer, userInfo: ^Dictionary) -> ^Error { return msgSend(^Error, Error, "errorWithDomain:code:userInfo:", domain, code, userInfo) } diff --git a/core/sys/darwin/Foundation/NSLock.odin b/core/sys/darwin/Foundation/NSLock.odin index 3bcc06eab..c48b5dbad 100644 --- a/core/sys/darwin/Foundation/NSLock.odin +++ b/core/sys/darwin/Foundation/NSLock.odin @@ -13,7 +13,7 @@ Locking_unlock :: proc(self: ^Locking($T)) { Condition :: struct {using _: Locking(Condition) } -@(objc_type=Condition, objc_class_name="alloc") +@(objc_type=Condition, objc_name="alloc", objc_is_class_method=true) Condition_alloc :: proc() -> ^Condition { return msgSend(^Condition, Condition, "alloc") } diff --git a/core/sys/darwin/Foundation/NSNotification.odin b/core/sys/darwin/Foundation/NSNotification.odin index d8b142e53..182d33896 100644 --- a/core/sys/darwin/Foundation/NSNotification.odin +++ b/core/sys/darwin/Foundation/NSNotification.odin @@ -4,7 +4,7 @@ package objc_Foundation Notification :: struct{using _: Object} -@(objc_type=Notification, objc_class_name="alloc") +@(objc_type=Notification, objc_name="alloc", objc_is_class_method=true) Notification_alloc :: proc() -> ^Notification { return msgSend(^Notification, Notification, "alloc") } diff --git a/core/sys/darwin/Foundation/NSNumber.odin b/core/sys/darwin/Foundation/NSNumber.odin index f77b0866a..4f7ef311b 100644 --- a/core/sys/darwin/Foundation/NSNumber.odin +++ b/core/sys/darwin/Foundation/NSNumber.odin @@ -8,7 +8,7 @@ import "core:c" @(objc_class="NSValue") Value :: struct{using _: Copying(Value)} -@(objc_type=Value, objc_class_name="alloc") +@(objc_type=Value, objc_name="alloc", objc_is_class_method=true) Value_alloc :: proc() -> ^Value { return msgSend(^Value, Value, "alloc") } @@ -18,12 +18,12 @@ Value_init :: proc(self: ^Value) -> ^Value { return msgSend(^Value, self, "init") } -@(objc_type=Value, objc_class_name="valueWithBytes") +@(objc_type=Value, objc_name="valueWithBytes", objc_is_class_method=true) Value_valueWithBytes :: proc(value: rawptr, type: cstring) -> ^Value { return msgSend(^Value, Value, "valueWithBytes:objCType:", value, type) } -@(objc_type=Value, objc_class_name="valueWithPointer") +@(objc_type=Value, objc_name="valueWithPointer", objc_is_class_method=true) Value_valueWithPointer :: proc(pointer: rawptr) -> ^Value { return msgSend(^Value, Value, "valueWithPointer:", pointer) } @@ -64,7 +64,7 @@ Value_pointerValue :: proc(self: ^Value) -> rawptr { Number :: struct{using _: Copying(Number), using _: Value} -@(objc_type=Number, objc_class_name="alloc") +@(objc_type=Number, objc_name="alloc", objc_is_class_method=true) Number_alloc :: proc() -> ^Number { return msgSend(^Number, Number, "alloc") } @@ -74,19 +74,19 @@ Number_init :: proc(self: ^Number) -> ^Number { return msgSend(^Number, self, "init") } -@(objc_type=Number, objc_class_name="numberWithI8") Number_numberWithI8 :: proc(value: i8) -> ^Number { return msgSend(^Number, Number, "numberWithChar:", value) } -@(objc_type=Number, objc_class_name="numberWithU8") Number_numberWithU8 :: proc(value: u8) -> ^Number { return msgSend(^Number, Number, "numberWithUnsignedChar:", value) } -@(objc_type=Number, objc_class_name="numberWithI16") Number_numberWithI16 :: proc(value: i16) -> ^Number { return msgSend(^Number, Number, "numberWithShort:", value) } -@(objc_type=Number, objc_class_name="numberWithU16") Number_numberWithU16 :: proc(value: u16) -> ^Number { return msgSend(^Number, Number, "numberWithUnsignedShort:", value) } -@(objc_type=Number, objc_class_name="numberWithI32") Number_numberWithI32 :: proc(value: i32) -> ^Number { return msgSend(^Number, Number, "numberWithInt:", value) } -@(objc_type=Number, objc_class_name="numberWithU32") Number_numberWithU32 :: proc(value: u32) -> ^Number { return msgSend(^Number, Number, "numberWithUnsignedInt:", value) } -@(objc_type=Number, objc_class_name="numberWithInt") Number_numberWithInt :: proc(value: int) -> ^Number { return msgSend(^Number, Number, "numberWithLong:", value) } -@(objc_type=Number, objc_class_name="numberWithUint") Number_numberWithUint :: proc(value: uint) -> ^Number { return msgSend(^Number, Number, "numberWithUnsignedLong:", value) } -@(objc_type=Number, objc_class_name="numberWithU64") Number_numberWithU64 :: proc(value: u64) -> ^Number { return msgSend(^Number, Number, "numberWithLongLong:", value) } -@(objc_type=Number, objc_class_name="numberWithI64") Number_numberWithI64 :: proc(value: i64) -> ^Number { return msgSend(^Number, Number, "numberWithUnsignedLongLong:", value) } -@(objc_type=Number, objc_class_name="numberWithF32") Number_numberWithF32 :: proc(value: f32) -> ^Number { return msgSend(^Number, Number, "numberWithFloat:", value) } -@(objc_type=Number, objc_class_name="numberWithF64") Number_numberWithF64 :: proc(value: f64) -> ^Number { return msgSend(^Number, Number, "numberWithDouble:", value) } -@(objc_type=Number, objc_class_name="numberWithBool") Number_numberWithBool :: proc(value: BOOL) -> ^Number { return msgSend(^Number, Number, "numberWithBool:", value) } +@(objc_type=Number, objc_name="numberWithI8", objc_is_class_method=true) Number_numberWithI8 :: proc(value: i8) -> ^Number { return msgSend(^Number, Number, "numberWithChar:", value) } +@(objc_type=Number, objc_name="numberWithU8", objc_is_class_method=true) Number_numberWithU8 :: proc(value: u8) -> ^Number { return msgSend(^Number, Number, "numberWithUnsignedChar:", value) } +@(objc_type=Number, objc_name="numberWithI16", objc_is_class_method=true) Number_numberWithI16 :: proc(value: i16) -> ^Number { return msgSend(^Number, Number, "numberWithShort:", value) } +@(objc_type=Number, objc_name="numberWithU16", objc_is_class_method=true) Number_numberWithU16 :: proc(value: u16) -> ^Number { return msgSend(^Number, Number, "numberWithUnsignedShort:", value) } +@(objc_type=Number, objc_name="numberWithI32", objc_is_class_method=true) Number_numberWithI32 :: proc(value: i32) -> ^Number { return msgSend(^Number, Number, "numberWithInt:", value) } +@(objc_type=Number, objc_name="numberWithU32", objc_is_class_method=true) Number_numberWithU32 :: proc(value: u32) -> ^Number { return msgSend(^Number, Number, "numberWithUnsignedInt:", value) } +@(objc_type=Number, objc_name="numberWithInt", objc_is_class_method=true) Number_numberWithInt :: proc(value: int) -> ^Number { return msgSend(^Number, Number, "numberWithLong:", value) } +@(objc_type=Number, objc_name="numberWithUint", objc_is_class_method=true) Number_numberWithUint :: proc(value: uint) -> ^Number { return msgSend(^Number, Number, "numberWithUnsignedLong:", value) } +@(objc_type=Number, objc_name="numberWithU64", objc_is_class_method=true) Number_numberWithU64 :: proc(value: u64) -> ^Number { return msgSend(^Number, Number, "numberWithLongLong:", value) } +@(objc_type=Number, objc_name="numberWithI64", objc_is_class_method=true) Number_numberWithI64 :: proc(value: i64) -> ^Number { return msgSend(^Number, Number, "numberWithUnsignedLongLong:", value) } +@(objc_type=Number, objc_name="numberWithF32", objc_is_class_method=true) Number_numberWithF32 :: proc(value: f32) -> ^Number { return msgSend(^Number, Number, "numberWithFloat:", value) } +@(objc_type=Number, objc_name="numberWithF64", objc_is_class_method=true) Number_numberWithF64 :: proc(value: f64) -> ^Number { return msgSend(^Number, Number, "numberWithDouble:", value) } +@(objc_type=Number, objc_name="numberWithBool", objc_is_class_method=true) Number_numberWithBool :: proc(value: BOOL) -> ^Number { return msgSend(^Number, Number, "numberWithBool:", value) } Number_number :: proc{ Number_numberWithI8, diff --git a/core/sys/darwin/Foundation/NSString.odin b/core/sys/darwin/Foundation/NSString.odin index 06dbc27a3..66442383a 100644 --- a/core/sys/darwin/Foundation/NSString.odin +++ b/core/sys/darwin/Foundation/NSString.odin @@ -59,7 +59,7 @@ MakeConstantString :: proc "c" (#const c: cstring) -> ^String { } -@(objc_type=String, objc_class_name="alloc") +@(objc_type=String, objc_name="alloc", objc_is_class_method=true) String_alloc :: proc() -> ^String { return msgSend(^String, String, "alloc") } diff --git a/core/sys/darwin/Foundation/NSURL.odin b/core/sys/darwin/Foundation/NSURL.odin index 42edf91c0..9813b6e59 100644 --- a/core/sys/darwin/Foundation/NSURL.odin +++ b/core/sys/darwin/Foundation/NSURL.odin @@ -4,7 +4,7 @@ package objc_Foundation URL :: struct{using _: Copying(URL)} -@(objc_type=URL, objc_class_name="alloc") +@(objc_type=URL, objc_name="alloc", objc_is_class_method=true) URL_alloc :: proc() -> ^URL { return msgSend(^URL, URL, "alloc") } diff --git a/core/sys/darwin/Metal/MetalClasses.odin b/core/sys/darwin/Metal/MetalClasses.odin index 7472fa37b..2686ce2ae 100644 --- a/core/sys/darwin/Metal/MetalClasses.odin +++ b/core/sys/darwin/Metal/MetalClasses.odin @@ -24,7 +24,7 @@ Methods: @(objc_class="MTLAccelerationStructureBoundingBoxGeometryDescriptor") AccelerationStructureBoundingBoxGeometryDescriptor :: struct { using _: NS.Copying(AccelerationStructureBoundingBoxGeometryDescriptor), using _: AccelerationStructureDescriptor } -@(objc_type=AccelerationStructureBoundingBoxGeometryDescriptor, objc_class_name="alloc") +@(objc_type=AccelerationStructureBoundingBoxGeometryDescriptor, objc_name="alloc", objc_is_class_method=true) AccelerationStructureBoundingBoxGeometryDescriptor_alloc :: #force_inline proc() -> ^AccelerationStructureBoundingBoxGeometryDescriptor { return msgSend(^AccelerationStructureBoundingBoxGeometryDescriptor, AccelerationStructureBoundingBoxGeometryDescriptor, "alloc") } @@ -48,7 +48,7 @@ AccelerationStructureBoundingBoxGeometryDescriptor_boundingBoxCount :: #force_in AccelerationStructureBoundingBoxGeometryDescriptor_boundingBoxStride :: #force_inline proc(self: ^AccelerationStructureBoundingBoxGeometryDescriptor) -> NS.UInteger { return msgSend(NS.UInteger, self, "boundingBoxStride") } -@(objc_type=AccelerationStructureBoundingBoxGeometryDescriptor, objc_class_name="descriptor") +@(objc_type=AccelerationStructureBoundingBoxGeometryDescriptor, objc_name="descriptor", objc_is_class_method=true) AccelerationStructureBoundingBoxGeometryDescriptor_descriptor :: #force_inline proc() -> ^AccelerationStructureBoundingBoxGeometryDescriptor { return msgSend(^AccelerationStructureBoundingBoxGeometryDescriptor, AccelerationStructureBoundingBoxGeometryDescriptor, "descriptor") } @@ -88,31 +88,31 @@ Methods: @(objc_class="MTLMotionKeyframeData") MotionKeyframeData :: struct { using _: NS.Object } -@(objc_type=MotionKeyframeData, objc_class_name="alloc") +@(objc_type=MotionKeyframeData, objc_name="alloc", objc_is_class_method=true) MotionKeyframeData_alloc :: #force_inline proc() -> ^MotionKeyframeData { return msgSend(^MotionKeyframeData, MotionKeyframeData, "alloc") } -@(objc_type=MotionKeyframeData, objc_class_name="data") +@(objc_type=MotionKeyframeData, objc_name="data", objc_is_class_method=true) MotionKeyframeData_data :: #force_inline proc() -> ^MotionKeyframeData { return msgSend(^MotionKeyframeData, MotionKeyframeData, "data") } -@(objc_type=MotionKeyframeData, objc_class_name="init") +@(objc_type=MotionKeyframeData, objc_name="init", objc_is_class_method=true) MotionKeyframeData_init :: #force_inline proc(self: ^MotionKeyframeData) -> ^MotionKeyframeData { return msgSend(^MotionKeyframeData, self, "init") } -@(objc_type=MotionKeyframeData, objc_class_name="buffer") +@(objc_type=MotionKeyframeData, objc_name="buffer", objc_is_class_method=true) MotionKeyframeData_buffer :: #force_inline proc(self: ^MotionKeyframeData) -> ^Buffer { return msgSend(^Buffer, self, "buffer") } -@(objc_type=MotionKeyframeData, objc_class_name="setBuffer") +@(objc_type=MotionKeyframeData, objc_name="setBuffer", objc_is_class_method=true) MotionKeyframeData_setBuffer :: #force_inline proc(self: ^MotionKeyframeData, buffer: ^Buffer) { msgSend(nil, self, "setBuffer:", buffer) } -@(objc_type=MotionKeyframeData, objc_class_name="offset") +@(objc_type=MotionKeyframeData, objc_name="offset", objc_is_class_method=true) MotionKeyframeData_offset :: #force_inline proc(self: ^MotionKeyframeData) -> NS.UInteger { return msgSend(NS.UInteger, self, "offset") } -@(objc_type=MotionKeyframeData, objc_class_name="setOffset") +@(objc_type=MotionKeyframeData, objc_name="setOffset", objc_is_class_method=true) MotionKeyframeData_setOffset :: #force_inline proc(self: ^MotionKeyframeData, offset: NS.UInteger) { msgSend(nil, self, "setOffset:", offset) } @@ -127,7 +127,7 @@ Class: @(objc_class="MTLAccelerationStructureMotionTriangleGeometryDescriptor") AccelerationStructureMotionTriangleGeometryDescriptor :: struct { using _: NS.Copying(AccelerationStructureMotionTriangleGeometryDescriptor), using _: AccelerationStructureGeometryDescriptor } -@(objc_type=AccelerationStructureMotionTriangleGeometryDescriptor, objc_class_name="alloc") +@(objc_type=AccelerationStructureMotionTriangleGeometryDescriptor, objc_name="alloc", objc_is_class_method=true) AccelerationStructureMotionTriangleGeometryDescriptor_alloc :: #force_inline proc() -> ^AccelerationStructureMotionTriangleGeometryDescriptor { return msgSend(^AccelerationStructureMotionTriangleGeometryDescriptor, AccelerationStructureMotionTriangleGeometryDescriptor, "alloc") } @@ -202,7 +202,7 @@ Class: @(objc_class="MTLAccelerationStructureMotionBoundingBoxGeometryDescriptor") AccelerationStructureMotionBoundingBoxGeometryDescriptor :: struct { using _: NS.Copying(AccelerationStructureMotionBoundingBoxGeometryDescriptor), using _: AccelerationStructureGeometryDescriptor } -@(objc_type=AccelerationStructureMotionBoundingBoxGeometryDescriptor, objc_class_name="alloc") +@(objc_type=AccelerationStructureMotionBoundingBoxGeometryDescriptor, objc_name="alloc", objc_is_class_method=true) AccelerationStructureMotionBoundingBoxGeometryDescriptor_alloc :: #force_inline proc() -> ^AccelerationStructureMotionBoundingBoxGeometryDescriptor { return msgSend(^AccelerationStructureMotionBoundingBoxGeometryDescriptor, AccelerationStructureMotionBoundingBoxGeometryDescriptor, "alloc") } @@ -211,7 +211,7 @@ AccelerationStructureMotionBoundingBoxGeometryDescriptor_init :: #force_inline p return msgSend(^AccelerationStructureMotionBoundingBoxGeometryDescriptor, self, "init") } -@(objc_type=AccelerationStructureMotionBoundingBoxGeometryDescriptor, objc_class_name="descriptor") +@(objc_type=AccelerationStructureMotionBoundingBoxGeometryDescriptor, objc_name="descriptor", objc_is_class_method=true) AccelerationStructureMotionBoundingBoxGeometryDescriptor_descriptor :: #force_inline proc() -> ^AccelerationStructureMotionBoundingBoxGeometryDescriptor { return msgSend(^AccelerationStructureMotionBoundingBoxGeometryDescriptor, AccelerationStructureMotionBoundingBoxGeometryDescriptor, "descriptor") } @@ -264,7 +264,7 @@ Methods: @(objc_class="MTLAccelerationStructureDescriptor") AccelerationStructureDescriptor :: struct { using _: NS.Copying(AccelerationStructureDescriptor) } -@(objc_type=AccelerationStructureDescriptor, objc_class_name="alloc") +@(objc_type=AccelerationStructureDescriptor, objc_name="alloc", objc_is_class_method=true) AccelerationStructureDescriptor_alloc :: #force_inline proc() -> ^AccelerationStructureDescriptor { return msgSend(^AccelerationStructureDescriptor, AccelerationStructureDescriptor, "alloc") } @@ -300,7 +300,7 @@ Methods: @(objc_class="MTLAccelerationStructureGeometryDescriptor") AccelerationStructureGeometryDescriptor :: struct { using _: NS.Copying(AccelerationStructureGeometryDescriptor) } -@(objc_type=AccelerationStructureGeometryDescriptor, objc_class_name="alloc") +@(objc_type=AccelerationStructureGeometryDescriptor, objc_name="alloc", objc_is_class_method=true) AccelerationStructureGeometryDescriptor_alloc :: #force_inline proc() -> ^AccelerationStructureGeometryDescriptor { return msgSend(^AccelerationStructureGeometryDescriptor, AccelerationStructureGeometryDescriptor, "alloc") } @@ -361,7 +361,7 @@ Methods: @(objc_class="MTLAccelerationStructureTriangleGeometryDescriptor") AccelerationStructureTriangleGeometryDescriptor :: struct { using _: NS.Copying(AccelerationStructureTriangleGeometryDescriptor), using _: AccelerationStructureDescriptor } -@(objc_type=AccelerationStructureTriangleGeometryDescriptor, objc_class_name="alloc") +@(objc_type=AccelerationStructureTriangleGeometryDescriptor, objc_name="alloc", objc_is_class_method=true) AccelerationStructureTriangleGeometryDescriptor_alloc :: #force_inline proc() -> ^AccelerationStructureTriangleGeometryDescriptor { return msgSend(^AccelerationStructureTriangleGeometryDescriptor, AccelerationStructureTriangleGeometryDescriptor, "alloc") } @@ -369,7 +369,7 @@ AccelerationStructureTriangleGeometryDescriptor_alloc :: #force_inline proc() -> AccelerationStructureTriangleGeometryDescriptor_init :: #force_inline proc(self: ^AccelerationStructureTriangleGeometryDescriptor) -> ^AccelerationStructureTriangleGeometryDescriptor { return msgSend(^AccelerationStructureTriangleGeometryDescriptor, self, "init") } -@(objc_type=AccelerationStructureTriangleGeometryDescriptor, objc_class_name="descriptor") +@(objc_type=AccelerationStructureTriangleGeometryDescriptor, objc_name="descriptor", objc_is_class_method=true) AccelerationStructureTriangleGeometryDescriptor_descriptor :: #force_inline proc() -> ^AccelerationStructureTriangleGeometryDescriptor { return msgSend(^AccelerationStructureTriangleGeometryDescriptor, AccelerationStructureTriangleGeometryDescriptor, "descriptor") } @@ -459,7 +459,7 @@ Methods: @(objc_class="MTLArgument") Argument :: struct { using _: NS.Object } -@(objc_type=Argument, objc_class_name="alloc") +@(objc_type=Argument, objc_name="alloc", objc_is_class_method=true) Argument_alloc :: #force_inline proc() -> ^Argument { return msgSend(^Argument, Argument, "alloc") } @@ -558,7 +558,7 @@ Methods: @(objc_class="MTLArgumentDescriptor") ArgumentDescriptor :: struct { using _: NS.Copying(ArgumentDescriptor) } -@(objc_type=ArgumentDescriptor, objc_class_name="alloc") +@(objc_type=ArgumentDescriptor, objc_name="alloc", objc_is_class_method=true) ArgumentDescriptor_alloc :: #force_inline proc() -> ^ArgumentDescriptor { return msgSend(^ArgumentDescriptor, ArgumentDescriptor, "alloc") } @@ -570,7 +570,7 @@ ArgumentDescriptor_init :: #force_inline proc(self: ^ArgumentDescriptor) -> ^Arg ArgumentDescriptor_access :: #force_inline proc(self: ^ArgumentDescriptor) -> ArgumentAccess { return msgSend(ArgumentAccess, self, "access") } -@(objc_type=ArgumentDescriptor, objc_class_name="argumentDescriptor") +@(objc_type=ArgumentDescriptor, objc_name="argumentDescriptor", objc_is_class_method=true) ArgumentDescriptor_argumentDescriptor :: #force_inline proc() -> ^ArgumentDescriptor { return msgSend(^ArgumentDescriptor, ArgumentDescriptor, "argumentDescriptor") } @@ -640,7 +640,7 @@ Methods: @(objc_class="MTLArrayType") ArrayType :: struct { using _: Type } -@(objc_type=ArrayType, objc_class_name="alloc") +@(objc_type=ArrayType, objc_name="alloc", objc_is_class_method=true) ArrayType_alloc :: #force_inline proc() -> ^ArrayType { return msgSend(^ArrayType, ArrayType, "alloc") } @@ -700,7 +700,7 @@ Methods: @(objc_class="MTLAttribute") Attribute :: struct { using _: NS.Object } -@(objc_type=Attribute, objc_class_name="alloc") +@(objc_type=Attribute, objc_name="alloc", objc_is_class_method=true) Attribute_alloc :: #force_inline proc() -> ^Attribute { return msgSend(^Attribute, Attribute, "alloc") } @@ -752,7 +752,7 @@ Methods: @(objc_class="MTLAttributeDescriptor") AttributeDescriptor :: struct { using _: NS.Copying(AttributeDescriptor) } -@(objc_type=AttributeDescriptor, objc_class_name="alloc") +@(objc_type=AttributeDescriptor, objc_name="alloc", objc_is_class_method=true) AttributeDescriptor_alloc :: #force_inline proc() -> ^AttributeDescriptor { return msgSend(^AttributeDescriptor, AttributeDescriptor, "alloc") } @@ -800,7 +800,7 @@ Methods: @(objc_class="MTLAttributeDescriptorArray") AttributeDescriptorArray :: struct { using _: NS.Object } -@(objc_type=AttributeDescriptorArray, objc_class_name="alloc") +@(objc_type=AttributeDescriptorArray, objc_name="alloc", objc_is_class_method=true) AttributeDescriptorArray_alloc :: #force_inline proc() -> ^AttributeDescriptorArray { return msgSend(^AttributeDescriptorArray, AttributeDescriptorArray, "alloc") } @@ -832,7 +832,7 @@ Methods: @(objc_class="MTLBinaryArchiveDescriptor") BinaryArchiveDescriptor :: struct { using _: NS.Copying(BinaryArchiveDescriptor) } -@(objc_type=BinaryArchiveDescriptor, objc_class_name="alloc") +@(objc_type=BinaryArchiveDescriptor, objc_name="alloc", objc_is_class_method=true) BinaryArchiveDescriptor_alloc :: #force_inline proc() -> ^BinaryArchiveDescriptor { return msgSend(^BinaryArchiveDescriptor, BinaryArchiveDescriptor, "alloc") } @@ -864,7 +864,7 @@ Methods: @(objc_class="MTLBlitPassDescriptor") BlitPassDescriptor :: struct { using _: NS.Copying(BlitPassDescriptor) } -@(objc_type=BlitPassDescriptor, objc_class_name="alloc") +@(objc_type=BlitPassDescriptor, objc_name="alloc", objc_is_class_method=true) BlitPassDescriptor_alloc :: #force_inline proc() -> ^BlitPassDescriptor { return msgSend(^BlitPassDescriptor, BlitPassDescriptor, "alloc") } @@ -872,7 +872,7 @@ BlitPassDescriptor_alloc :: #force_inline proc() -> ^BlitPassDescriptor { BlitPassDescriptor_init :: #force_inline proc(self: ^BlitPassDescriptor) -> ^BlitPassDescriptor { return msgSend(^BlitPassDescriptor, self, "init") } -@(objc_type=BlitPassDescriptor, objc_class_name="blitPassDescriptor") +@(objc_type=BlitPassDescriptor, objc_name="blitPassDescriptor", objc_is_class_method=true) BlitPassDescriptor_blitPassDescriptor :: #force_inline proc() -> ^BlitPassDescriptor { return msgSend(^BlitPassDescriptor, BlitPassDescriptor, "blitPassDescriptor") } @@ -900,7 +900,7 @@ Methods: @(objc_class="MTLBlitPassSampleBufferAttachmentDescriptor") BlitPassSampleBufferAttachmentDescriptor :: struct { using _: NS.Copying(BlitPassSampleBufferAttachmentDescriptor) } -@(objc_type=BlitPassSampleBufferAttachmentDescriptor, objc_class_name="alloc") +@(objc_type=BlitPassSampleBufferAttachmentDescriptor, objc_name="alloc", objc_is_class_method=true) BlitPassSampleBufferAttachmentDescriptor_alloc :: #force_inline proc() -> ^BlitPassSampleBufferAttachmentDescriptor { return msgSend(^BlitPassSampleBufferAttachmentDescriptor, BlitPassSampleBufferAttachmentDescriptor, "alloc") } @@ -948,7 +948,7 @@ Methods: @(objc_class="MTLBlitPassSampleBufferAttachmentDescriptorArray") BlitPassSampleBufferAttachmentDescriptorArray :: struct { using _: NS.Object } -@(objc_type=BlitPassSampleBufferAttachmentDescriptorArray, objc_class_name="alloc") +@(objc_type=BlitPassSampleBufferAttachmentDescriptorArray, objc_name="alloc", objc_is_class_method=true) BlitPassSampleBufferAttachmentDescriptorArray_alloc :: #force_inline proc() -> ^BlitPassSampleBufferAttachmentDescriptorArray { return msgSend(^BlitPassSampleBufferAttachmentDescriptorArray, BlitPassSampleBufferAttachmentDescriptorArray, "alloc") } @@ -984,7 +984,7 @@ Methods: @(objc_class="MTLBufferLayoutDescriptor") BufferLayoutDescriptor :: struct { using _: NS.Copying(BufferLayoutDescriptor) } -@(objc_type=BufferLayoutDescriptor, objc_class_name="alloc") +@(objc_type=BufferLayoutDescriptor, objc_name="alloc", objc_is_class_method=true) BufferLayoutDescriptor_alloc :: #force_inline proc() -> ^BufferLayoutDescriptor { return msgSend(^BufferLayoutDescriptor, BufferLayoutDescriptor, "alloc") } @@ -1032,7 +1032,7 @@ Methods: @(objc_class="MTLBufferLayoutDescriptorArray") BufferLayoutDescriptorArray :: struct { using _: NS.Object } -@(objc_type=BufferLayoutDescriptorArray, objc_class_name="alloc") +@(objc_type=BufferLayoutDescriptorArray, objc_name="alloc", objc_is_class_method=true) BufferLayoutDescriptorArray_alloc :: #force_inline proc() -> ^BufferLayoutDescriptorArray { return msgSend(^BufferLayoutDescriptorArray, BufferLayoutDescriptorArray, "alloc") } @@ -1068,7 +1068,7 @@ Methods: @(objc_class="MTLCaptureDescriptor") CaptureDescriptor :: struct { using _: NS.Copying(CaptureDescriptor) } -@(objc_type=CaptureDescriptor, objc_class_name="alloc") +@(objc_type=CaptureDescriptor, objc_name="alloc", objc_is_class_method=true) CaptureDescriptor_alloc :: #force_inline proc() -> ^CaptureDescriptor { return msgSend(^CaptureDescriptor, CaptureDescriptor, "alloc") } @@ -1126,7 +1126,7 @@ Methods: @(objc_class="MTLCaptureManager") CaptureManager :: struct { using _: NS.Object } -@(objc_type=CaptureManager, objc_class_name="alloc") +@(objc_type=CaptureManager, objc_name="alloc", objc_is_class_method=true) CaptureManager_alloc :: #force_inline proc() -> ^CaptureManager { return msgSend(^CaptureManager, CaptureManager, "alloc") } @@ -1154,7 +1154,7 @@ CaptureManager_newCaptureScopeWithDevice :: #force_inline proc(self: ^CaptureMan CaptureManager_setDefaultCaptureScope :: #force_inline proc(self: ^CaptureManager, defaultCaptureScope: ^CaptureScope) { msgSend(nil, self, "setDefaultCaptureScope:", defaultCaptureScope) } -@(objc_type=CaptureManager, objc_class_name="sharedCaptureManager") +@(objc_type=CaptureManager, objc_name="sharedCaptureManager", objc_is_class_method=true) CaptureManager_sharedCaptureManager :: #force_inline proc() -> ^CaptureManager { return msgSend(^CaptureManager, CaptureManager, "sharedCaptureManager") } @@ -1201,7 +1201,7 @@ Methods: @(objc_class="MTLCommandBufferDescriptor") CommandBufferDescriptor :: struct { using _: NS.Copying(CommandBufferDescriptor) } -@(objc_type=CommandBufferDescriptor, objc_class_name="alloc") +@(objc_type=CommandBufferDescriptor, objc_name="alloc", objc_is_class_method=true) CommandBufferDescriptor_alloc :: #force_inline proc() -> ^CommandBufferDescriptor { return msgSend(^CommandBufferDescriptor, CommandBufferDescriptor, "alloc") } @@ -1253,7 +1253,7 @@ Methods: @(objc_class="MTLCompileOptions") CompileOptions :: struct { using _: NS.Copying(CompileOptions) } -@(objc_type=CompileOptions, objc_class_name="alloc") +@(objc_type=CompileOptions, objc_name="alloc", objc_is_class_method=true) CompileOptions_alloc :: #force_inline proc() -> ^CompileOptions { return msgSend(^CompileOptions, CompileOptions, "alloc") } @@ -1335,7 +1335,7 @@ Methods: @(objc_class="MTLComputePassDescriptor") ComputePassDescriptor :: struct { using _: NS.Copying(ComputePassDescriptor) } -@(objc_type=ComputePassDescriptor, objc_class_name="alloc") +@(objc_type=ComputePassDescriptor, objc_name="alloc", objc_is_class_method=true) ComputePassDescriptor_alloc :: #force_inline proc() -> ^ComputePassDescriptor { return msgSend(^ComputePassDescriptor, ComputePassDescriptor, "alloc") } @@ -1343,7 +1343,7 @@ ComputePassDescriptor_alloc :: #force_inline proc() -> ^ComputePassDescriptor { ComputePassDescriptor_init :: #force_inline proc(self: ^ComputePassDescriptor) -> ^ComputePassDescriptor { return msgSend(^ComputePassDescriptor, self, "init") } -@(objc_type=ComputePassDescriptor, objc_class_name="computePassDescriptor") +@(objc_type=ComputePassDescriptor, objc_name="computePassDescriptor", objc_is_class_method=true) ComputePassDescriptor_computePassDescriptor :: #force_inline proc() -> ^ComputePassDescriptor { return msgSend(^ComputePassDescriptor, ComputePassDescriptor, "computePassDescriptor") } @@ -1379,7 +1379,7 @@ Methods: @(objc_class="MTLComputePassSampleBufferAttachmentDescriptor") ComputePassSampleBufferAttachmentDescriptor :: struct { using _: NS.Copying(ComputePassSampleBufferAttachmentDescriptor) } -@(objc_type=ComputePassSampleBufferAttachmentDescriptor, objc_class_name="alloc") +@(objc_type=ComputePassSampleBufferAttachmentDescriptor, objc_name="alloc", objc_is_class_method=true) ComputePassSampleBufferAttachmentDescriptor_alloc :: #force_inline proc() -> ^ComputePassSampleBufferAttachmentDescriptor { return msgSend(^ComputePassSampleBufferAttachmentDescriptor, ComputePassSampleBufferAttachmentDescriptor, "alloc") } @@ -1427,7 +1427,7 @@ Methods: @(objc_class="MTLComputePassSampleBufferAttachmentDescriptorArray") ComputePassSampleBufferAttachmentDescriptorArray :: struct { using _: NS.Object } -@(objc_type=ComputePassSampleBufferAttachmentDescriptorArray, objc_class_name="alloc") +@(objc_type=ComputePassSampleBufferAttachmentDescriptorArray, objc_name="alloc", objc_is_class_method=true) ComputePassSampleBufferAttachmentDescriptorArray_alloc :: #force_inline proc() -> ^ComputePassSampleBufferAttachmentDescriptorArray { return msgSend(^ComputePassSampleBufferAttachmentDescriptorArray, ComputePassSampleBufferAttachmentDescriptorArray, "alloc") } @@ -1481,7 +1481,7 @@ Methods: @(objc_class="MTLComputePipelineDescriptor") ComputePipelineDescriptor :: struct { using _: NS.Copying(ComputePipelineDescriptor) } -@(objc_type=ComputePipelineDescriptor, objc_class_name="alloc") +@(objc_type=ComputePipelineDescriptor, objc_name="alloc", objc_is_class_method=true) ComputePipelineDescriptor_alloc :: #force_inline proc() -> ^ComputePipelineDescriptor { return msgSend(^ComputePipelineDescriptor, ComputePipelineDescriptor, "alloc") } @@ -1600,7 +1600,7 @@ Methods: @(objc_class="MTLComputePipelineReflection") ComputePipelineReflection :: struct { using _: NS.Object } -@(objc_type=ComputePipelineReflection, objc_class_name="alloc") +@(objc_type=ComputePipelineReflection, objc_name="alloc", objc_is_class_method=true) ComputePipelineReflection_alloc :: #force_inline proc() -> ^ComputePipelineReflection { return msgSend(^ComputePipelineReflection, ComputePipelineReflection, "alloc") } @@ -1634,7 +1634,7 @@ Methods: @(objc_class="MTLCounterSampleBufferDescriptor") CounterSampleBufferDescriptor :: struct { using _: NS.Copying(CounterSampleBufferDescriptor) } -@(objc_type=CounterSampleBufferDescriptor, objc_class_name="alloc") +@(objc_type=CounterSampleBufferDescriptor, objc_name="alloc", objc_is_class_method=true) CounterSampleBufferDescriptor_alloc :: #force_inline proc() -> ^CounterSampleBufferDescriptor { return msgSend(^CounterSampleBufferDescriptor, CounterSampleBufferDescriptor, "alloc") } @@ -1698,7 +1698,7 @@ Methods: @(objc_class="MTLDepthStencilDescriptor") DepthStencilDescriptor :: struct { using _: NS.Copying(DepthStencilDescriptor) } -@(objc_type=DepthStencilDescriptor, objc_class_name="alloc") +@(objc_type=DepthStencilDescriptor, objc_name="alloc", objc_is_class_method=true) DepthStencilDescriptor_alloc :: #force_inline proc() -> ^DepthStencilDescriptor { return msgSend(^DepthStencilDescriptor, DepthStencilDescriptor, "alloc") } @@ -1764,7 +1764,7 @@ Methods: @(objc_class="MTLFunctionConstant") FunctionConstant :: struct { using _: NS.Copying(FunctionConstant) } -@(objc_type=FunctionConstant, objc_class_name="alloc") +@(objc_type=FunctionConstant, objc_name="alloc", objc_is_class_method=true) FunctionConstant_alloc :: #force_inline proc() -> ^FunctionConstant { return msgSend(^FunctionConstant, FunctionConstant, "alloc") } @@ -1806,7 +1806,7 @@ Methods: @(objc_class="MTLFunctionConstantValues") FunctionConstantValues :: struct { using _: NS.Copying(FunctionConstantValues) } -@(objc_type=FunctionConstantValues, objc_class_name="alloc") +@(objc_type=FunctionConstantValues, objc_name="alloc", objc_is_class_method=true) FunctionConstantValues_alloc :: #force_inline proc() -> ^FunctionConstantValues { return msgSend(^FunctionConstantValues, FunctionConstantValues, "alloc") } @@ -1853,7 +1853,7 @@ Methods: @(objc_class="MTLFunctionDescriptor") FunctionDescriptor :: struct { using _: NS.Copying(FunctionDescriptor) } -@(objc_type=FunctionDescriptor, objc_class_name="alloc") +@(objc_type=FunctionDescriptor, objc_name="alloc", objc_is_class_method=true) FunctionDescriptor_alloc :: #force_inline proc() -> ^FunctionDescriptor { return msgSend(^FunctionDescriptor, FunctionDescriptor, "alloc") } @@ -1865,7 +1865,7 @@ FunctionDescriptor_init :: #force_inline proc(self: ^FunctionDescriptor) -> ^Fun FunctionDescriptor_constantValues :: #force_inline proc(self: ^FunctionDescriptor) -> ^FunctionConstantValues { return msgSend(^FunctionConstantValues, self, "constantValues") } -@(objc_type=FunctionDescriptor, objc_class_name="functionDescriptor") +@(objc_type=FunctionDescriptor, objc_name="functionDescriptor", objc_is_class_method=true) FunctionDescriptor_functionDescriptor :: #force_inline proc() -> ^FunctionDescriptor { return msgSend(^FunctionDescriptor, FunctionDescriptor, "functionDescriptor") } @@ -1911,7 +1911,7 @@ Methods: @(objc_class="MTLIntersectionFunctionDescriptor") IntersectionFunctionDescriptor :: struct { using _: NS.Copying(IntersectionFunctionDescriptor) } -@(objc_type=IntersectionFunctionDescriptor, objc_class_name="alloc") +@(objc_type=IntersectionFunctionDescriptor, objc_name="alloc", objc_is_class_method=true) IntersectionFunctionDescriptor_alloc :: #force_inline proc() -> ^IntersectionFunctionDescriptor { return msgSend(^IntersectionFunctionDescriptor, IntersectionFunctionDescriptor, "alloc") } @@ -1945,7 +1945,7 @@ Methods: @(objc_class="MTLHeapDescriptor") HeapDescriptor :: struct { using _: NS.Copying(HeapDescriptor) } -@(objc_type=HeapDescriptor, objc_class_name="alloc") +@(objc_type=HeapDescriptor, objc_name="alloc", objc_is_class_method=true) HeapDescriptor_alloc :: #force_inline proc() -> ^HeapDescriptor { return msgSend(^HeapDescriptor, HeapDescriptor, "alloc") } @@ -2027,7 +2027,7 @@ Methods: @(objc_class="MTLIndirectCommandBufferDescriptor") IndirectCommandBufferDescriptor :: struct { using _: NS.Copying(IndirectCommandBufferDescriptor) } -@(objc_type=IndirectCommandBufferDescriptor, objc_class_name="alloc") +@(objc_type=IndirectCommandBufferDescriptor, objc_name="alloc", objc_is_class_method=true) IndirectCommandBufferDescriptor_alloc :: #force_inline proc() -> ^IndirectCommandBufferDescriptor { return msgSend(^IndirectCommandBufferDescriptor, IndirectCommandBufferDescriptor, "alloc") } @@ -2108,7 +2108,7 @@ Methods: @(objc_class="MTLInstanceAccelerationStructureDescriptor") InstanceAccelerationStructureDescriptor :: struct { using _: NS.Copying(InstanceAccelerationStructureDescriptor), using _: AccelerationStructureDescriptor } -@(objc_type=InstanceAccelerationStructureDescriptor, objc_class_name="alloc") +@(objc_type=InstanceAccelerationStructureDescriptor, objc_name="alloc", objc_is_class_method=true) InstanceAccelerationStructureDescriptor_alloc :: #force_inline proc() -> ^InstanceAccelerationStructureDescriptor { return msgSend(^InstanceAccelerationStructureDescriptor, InstanceAccelerationStructureDescriptor, "alloc") } @@ -2116,7 +2116,7 @@ InstanceAccelerationStructureDescriptor_alloc :: #force_inline proc() -> ^Instan InstanceAccelerationStructureDescriptor_init :: #force_inline proc(self: ^InstanceAccelerationStructureDescriptor) -> ^InstanceAccelerationStructureDescriptor { return msgSend(^InstanceAccelerationStructureDescriptor, self, "init") } -@(objc_type=InstanceAccelerationStructureDescriptor, objc_class_name="descriptor") +@(objc_type=InstanceAccelerationStructureDescriptor, objc_name="descriptor", objc_is_class_method=true) InstanceAccelerationStructureDescriptor_descriptor :: #force_inline proc() -> ^InstanceAccelerationStructureDescriptor { return msgSend(^InstanceAccelerationStructureDescriptor, InstanceAccelerationStructureDescriptor, "descriptor") } @@ -2217,7 +2217,7 @@ Methods: @(objc_class="MTLIntersectionFunctionTableDescriptor") IntersectionFunctionTableDescriptor :: struct { using _: NS.Copying(IntersectionFunctionTableDescriptor) } -@(objc_type=IntersectionFunctionTableDescriptor, objc_class_name="alloc") +@(objc_type=IntersectionFunctionTableDescriptor, objc_name="alloc", objc_is_class_method=true) IntersectionFunctionTableDescriptor_alloc :: #force_inline proc() -> ^IntersectionFunctionTableDescriptor { return msgSend(^IntersectionFunctionTableDescriptor, IntersectionFunctionTableDescriptor, "alloc") } @@ -2229,7 +2229,7 @@ IntersectionFunctionTableDescriptor_init :: #force_inline proc(self: ^Intersecti IntersectionFunctionTableDescriptor_functionCount :: #force_inline proc(self: ^IntersectionFunctionTableDescriptor) -> NS.UInteger { return msgSend(NS.UInteger, self, "functionCount") } -@(objc_type=IntersectionFunctionTableDescriptor, objc_class_name="intersectionFunctionTableDescriptor") +@(objc_type=IntersectionFunctionTableDescriptor, objc_name="intersectionFunctionTableDescriptor", objc_is_class_method=true) IntersectionFunctionTableDescriptor_intersectionFunctionTableDescriptor :: #force_inline proc() -> ^IntersectionFunctionTableDescriptor { return msgSend(^IntersectionFunctionTableDescriptor, IntersectionFunctionTableDescriptor, "intersectionFunctionTableDescriptor") } @@ -2258,7 +2258,7 @@ Methods: @(objc_class="MTLLinkedFunctions") LinkedFunctions :: struct { using _: NS.Copying(LinkedFunctions) } -@(objc_type=LinkedFunctions, objc_class_name="alloc") +@(objc_type=LinkedFunctions, objc_name="alloc", objc_is_class_method=true) LinkedFunctions_alloc :: #force_inline proc() -> ^LinkedFunctions { return msgSend(^LinkedFunctions, LinkedFunctions, "alloc") } @@ -2278,7 +2278,7 @@ LinkedFunctions_functions :: #force_inline proc(self: ^LinkedFunctions) -> ^NS.A LinkedFunctions_groups :: #force_inline proc(self: ^LinkedFunctions) -> ^NS.Dictionary { return msgSend(^NS.Dictionary, self, "groups") } -@(objc_type=LinkedFunctions, objc_class_name="linkedFunctions") +@(objc_type=LinkedFunctions, objc_name="linkedFunctions", objc_is_class_method=true) LinkedFunctions_linkedFunctions :: #force_inline proc() -> ^LinkedFunctions { return msgSend(^LinkedFunctions, LinkedFunctions, "linkedFunctions") } @@ -2310,7 +2310,7 @@ Methods: @(objc_class="MTLPipelineBufferDescriptor") PipelineBufferDescriptor :: struct { using _: NS.Copying(PipelineBufferDescriptor) } -@(objc_type=PipelineBufferDescriptor, objc_class_name="alloc") +@(objc_type=PipelineBufferDescriptor, objc_name="alloc", objc_is_class_method=true) PipelineBufferDescriptor_alloc :: #force_inline proc() -> ^PipelineBufferDescriptor { return msgSend(^PipelineBufferDescriptor, PipelineBufferDescriptor, "alloc") } @@ -2342,7 +2342,7 @@ Methods: @(objc_class="MTLPipelineBufferDescriptorArray") PipelineBufferDescriptorArray :: struct { using _: NS.Object } -@(objc_type=PipelineBufferDescriptorArray, objc_class_name="alloc") +@(objc_type=PipelineBufferDescriptorArray, objc_name="alloc", objc_is_class_method=true) PipelineBufferDescriptorArray_alloc :: #force_inline proc() -> ^PipelineBufferDescriptorArray { return msgSend(^PipelineBufferDescriptorArray, PipelineBufferDescriptorArray, "alloc") } @@ -2379,7 +2379,7 @@ Methods: @(objc_class="MTLPointerType") PointerType :: struct { using _: Type } -@(objc_type=PointerType, objc_class_name="alloc") +@(objc_type=PointerType, objc_name="alloc", objc_is_class_method=true) PointerType_alloc :: #force_inline proc() -> ^PointerType { return msgSend(^PointerType, PointerType, "alloc") } @@ -2432,7 +2432,7 @@ Methods: @(objc_class="MTLPrimitiveAccelerationStructureDescriptor") PrimitiveAccelerationStructureDescriptor :: struct { using _: NS.Copying(PrimitiveAccelerationStructureDescriptor), using _: AccelerationStructureDescriptor } -@(objc_type=PrimitiveAccelerationStructureDescriptor, objc_class_name="alloc") +@(objc_type=PrimitiveAccelerationStructureDescriptor, objc_name="alloc", objc_is_class_method=true) PrimitiveAccelerationStructureDescriptor_alloc :: #force_inline proc() -> ^PrimitiveAccelerationStructureDescriptor { return msgSend(^PrimitiveAccelerationStructureDescriptor, PrimitiveAccelerationStructureDescriptor, "alloc") } @@ -2440,7 +2440,7 @@ PrimitiveAccelerationStructureDescriptor_alloc :: #force_inline proc() -> ^Primi PrimitiveAccelerationStructureDescriptor_init :: #force_inline proc(self: ^PrimitiveAccelerationStructureDescriptor) -> ^PrimitiveAccelerationStructureDescriptor { return msgSend(^PrimitiveAccelerationStructureDescriptor, self, "init") } -@(objc_type=PrimitiveAccelerationStructureDescriptor, objc_class_name="descriptor") +@(objc_type=PrimitiveAccelerationStructureDescriptor, objc_name="descriptor", objc_is_class_method=true) PrimitiveAccelerationStructureDescriptor_descriptor :: #force_inline proc() -> ^PrimitiveAccelerationStructureDescriptor { return msgSend(^PrimitiveAccelerationStructureDescriptor, PrimitiveAccelerationStructureDescriptor, "descriptor") } @@ -2516,7 +2516,7 @@ Methods: @(objc_class="MTLRasterizationRateLayerArray") RasterizationRateLayerArray :: struct { using _: NS.Object } -@(objc_type=RasterizationRateLayerArray, objc_class_name="alloc") +@(objc_type=RasterizationRateLayerArray, objc_name="alloc", objc_is_class_method=true) RasterizationRateLayerArray_alloc :: #force_inline proc() -> ^RasterizationRateLayerArray { return msgSend(^RasterizationRateLayerArray, RasterizationRateLayerArray, "alloc") } @@ -2553,7 +2553,7 @@ Methods: @(objc_class="MTLRasterizationRateLayerDescriptor") RasterizationRateLayerDescriptor :: struct { using _: NS.Copying(RasterizationRateLayerDescriptor) } -@(objc_type=RasterizationRateLayerDescriptor, objc_class_name="alloc") +@(objc_type=RasterizationRateLayerDescriptor, objc_name="alloc", objc_is_class_method=true) RasterizationRateLayerDescriptor_alloc :: #force_inline proc() -> ^RasterizationRateLayerDescriptor { return msgSend(^RasterizationRateLayerDescriptor, RasterizationRateLayerDescriptor, "alloc") } @@ -2614,7 +2614,7 @@ Methods: @(objc_class="MTLRasterizationRateMapDescriptor") RasterizationRateMapDescriptor :: struct { using _: NS.Copying(RasterizationRateMapDescriptor) } -@(objc_type=RasterizationRateMapDescriptor, objc_class_name="alloc") +@(objc_type=RasterizationRateMapDescriptor, objc_name="alloc", objc_is_class_method=true) RasterizationRateMapDescriptor_alloc :: #force_inline proc() -> ^RasterizationRateMapDescriptor { return msgSend(^RasterizationRateMapDescriptor, RasterizationRateMapDescriptor, "alloc") } @@ -2638,15 +2638,15 @@ RasterizationRateMapDescriptor_layerCount :: #force_inline proc(self: ^Rasteriza RasterizationRateMapDescriptor_layers :: #force_inline proc(self: ^RasterizationRateMapDescriptor) -> ^RasterizationRateLayerArray { return msgSend(^RasterizationRateLayerArray, self, "layers") } -@(objc_type=RasterizationRateMapDescriptor, objc_class_name="rasterizationRateMapDescriptorWithScreenSize") +@(objc_type=RasterizationRateMapDescriptor, objc_name="rasterizationRateMapDescriptorWithScreenSize", objc_is_class_method=true) RasterizationRateMapDescriptor_rasterizationRateMapDescriptorWithScreenSize :: #force_inline proc(screenSize: Size) -> ^RasterizationRateMapDescriptor { return msgSend(^RasterizationRateMapDescriptor, RasterizationRateMapDescriptor, "rasterizationRateMapDescriptorWithScreenSize:", screenSize) } -@(objc_type=RasterizationRateMapDescriptor, objc_class_name="rasterizationRateMapDescriptorWithScreenSizeWithLayer") +@(objc_type=RasterizationRateMapDescriptor, objc_name="rasterizationRateMapDescriptorWithScreenSizeWithLayer", objc_is_class_method=true) RasterizationRateMapDescriptor_rasterizationRateMapDescriptorWithScreenSizeWithLayer :: #force_inline proc(screenSize: Size, layer: ^RasterizationRateLayerDescriptor) -> ^RasterizationRateMapDescriptor { return msgSend(^RasterizationRateMapDescriptor, RasterizationRateMapDescriptor, "rasterizationRateMapDescriptorWithScreenSize:layer:", screenSize, layer) } -@(objc_type=RasterizationRateMapDescriptor, objc_class_name="rasterizationRateMapDescriptorWithScreenSizeWithLayers") +@(objc_type=RasterizationRateMapDescriptor, objc_name="rasterizationRateMapDescriptorWithScreenSizeWithLayers", objc_is_class_method=true) RasterizationRateMapDescriptor_rasterizationRateMapDescriptorWithScreenSizeWithLayers :: #force_inline proc(screenSize: Size, layers: []^RasterizationRateLayerDescriptor) -> ^RasterizationRateMapDescriptor { return msgSend(^RasterizationRateMapDescriptor, RasterizationRateMapDescriptor, "rasterizationRateMapDescriptorWithScreenSize:layerCount:layers:", screenSize, NS.UInteger(len(layers)), layers) } @@ -2682,7 +2682,7 @@ Methods: @(objc_class="MTLRasterizationRateSampleArray") RasterizationRateSampleArray :: struct { using _: NS.Object } -@(objc_type=RasterizationRateSampleArray, objc_class_name="alloc") +@(objc_type=RasterizationRateSampleArray, objc_name="alloc", objc_is_class_method=true) RasterizationRateSampleArray_alloc :: #force_inline proc() -> ^RasterizationRateSampleArray { return msgSend(^RasterizationRateSampleArray, RasterizationRateSampleArray, "alloc") } @@ -2734,7 +2734,7 @@ Methods: @(objc_class="MTLRenderPassAttachmentDescriptor") RenderPassAttachmentDescriptor :: struct { using _: NS.Copying(RenderPassAttachmentDescriptor) } -@(objc_type=RenderPassAttachmentDescriptor, objc_class_name="alloc") +@(objc_type=RenderPassAttachmentDescriptor, objc_name="alloc", objc_is_class_method=true) RenderPassAttachmentDescriptor_alloc :: #force_inline proc() -> ^RenderPassAttachmentDescriptor { return msgSend(^RenderPassAttachmentDescriptor, RenderPassAttachmentDescriptor, "alloc") } @@ -2846,7 +2846,7 @@ Methods: @(objc_class="MTLRenderPassColorAttachmentDescriptor") RenderPassColorAttachmentDescriptor :: struct { using _: NS.Copying(RenderPassColorAttachmentDescriptor), using _: RenderPassAttachmentDescriptor } -@(objc_type=RenderPassColorAttachmentDescriptor, objc_class_name="alloc") +@(objc_type=RenderPassColorAttachmentDescriptor, objc_name="alloc", objc_is_class_method=true) RenderPassColorAttachmentDescriptor_alloc :: #force_inline proc() -> ^RenderPassColorAttachmentDescriptor { return msgSend(^RenderPassColorAttachmentDescriptor, RenderPassColorAttachmentDescriptor, "alloc") } @@ -2878,7 +2878,7 @@ Methods: @(objc_class="MTLRenderPassColorAttachmentDescriptorArray") RenderPassColorAttachmentDescriptorArray :: struct { using _: NS.Object } -@(objc_type=RenderPassColorAttachmentDescriptorArray, objc_class_name="alloc") +@(objc_type=RenderPassColorAttachmentDescriptorArray, objc_name="alloc", objc_is_class_method=true) RenderPassColorAttachmentDescriptorArray_alloc :: #force_inline proc() -> ^RenderPassColorAttachmentDescriptorArray { return msgSend(^RenderPassColorAttachmentDescriptorArray, RenderPassColorAttachmentDescriptorArray, "alloc") } @@ -2912,7 +2912,7 @@ Methods: @(objc_class="MTLRenderPassDepthAttachmentDescriptor") RenderPassDepthAttachmentDescriptor :: struct { using _: NS.Copying(RenderPassDepthAttachmentDescriptor), using _: RenderPassAttachmentDescriptor } -@(objc_type=RenderPassDepthAttachmentDescriptor, objc_class_name="alloc") +@(objc_type=RenderPassDepthAttachmentDescriptor, objc_name="alloc", objc_is_class_method=true) RenderPassDepthAttachmentDescriptor_alloc :: #force_inline proc() -> ^RenderPassDepthAttachmentDescriptor { return msgSend(^RenderPassDepthAttachmentDescriptor, RenderPassDepthAttachmentDescriptor, "alloc") } @@ -2979,7 +2979,7 @@ Methods: @(objc_class="MTLRenderPassDescriptor") RenderPassDescriptor :: struct { using _: NS.Copying(RenderPassDescriptor), using _: AccelerationStructureDescriptor } -@(objc_type=RenderPassDescriptor, objc_class_name="alloc") +@(objc_type=RenderPassDescriptor, objc_name="alloc", objc_is_class_method=true) RenderPassDescriptor_alloc :: #force_inline proc() -> ^RenderPassDescriptor { return msgSend(^RenderPassDescriptor, RenderPassDescriptor, "alloc") } @@ -3011,7 +3011,7 @@ RenderPassDescriptor_imageblockSampleLength :: #force_inline proc(self: ^RenderP RenderPassDescriptor_rasterizationRateMap :: #force_inline proc(self: ^RenderPassDescriptor) -> ^RasterizationRateMap { return msgSend(^RasterizationRateMap, self, "rasterizationRateMap") } -@(objc_type=RenderPassDescriptor, objc_class_name="renderPassDescriptor") +@(objc_type=RenderPassDescriptor, objc_name="renderPassDescriptor", objc_is_class_method=true) RenderPassDescriptor_renderPassDescriptor :: #force_inline proc() -> ^RenderPassDescriptor { return msgSend(^RenderPassDescriptor, RenderPassDescriptor, "renderPassDescriptor") } @@ -3127,7 +3127,7 @@ Methods: @(objc_class="MTLRenderPassSampleBufferAttachmentDescriptor") RenderPassSampleBufferAttachmentDescriptor :: struct { using _: NS.Copying(RenderPassSampleBufferAttachmentDescriptor) } -@(objc_type=RenderPassSampleBufferAttachmentDescriptor, objc_class_name="alloc") +@(objc_type=RenderPassSampleBufferAttachmentDescriptor, objc_name="alloc", objc_is_class_method=true) RenderPassSampleBufferAttachmentDescriptor_alloc :: #force_inline proc() -> ^RenderPassSampleBufferAttachmentDescriptor { return msgSend(^RenderPassSampleBufferAttachmentDescriptor, RenderPassSampleBufferAttachmentDescriptor, "alloc") } @@ -3191,7 +3191,7 @@ Methods: @(objc_class="MTLRenderPassSampleBufferAttachmentDescriptorArray") RenderPassSampleBufferAttachmentDescriptorArray :: struct { using _: NS.Object } -@(objc_type=RenderPassSampleBufferAttachmentDescriptorArray, objc_class_name="alloc") +@(objc_type=RenderPassSampleBufferAttachmentDescriptorArray, objc_name="alloc", objc_is_class_method=true) RenderPassSampleBufferAttachmentDescriptorArray_alloc :: #force_inline proc() -> ^RenderPassSampleBufferAttachmentDescriptorArray { return msgSend(^RenderPassSampleBufferAttachmentDescriptorArray, RenderPassSampleBufferAttachmentDescriptorArray, "alloc") } @@ -3225,7 +3225,7 @@ Methods: @(objc_class="MTLRenderPassStencilAttachmentDescriptor") RenderPassStencilAttachmentDescriptor :: struct { using _: NS.Copying(RenderPassStencilAttachmentDescriptor) } -@(objc_type=RenderPassStencilAttachmentDescriptor, objc_class_name="alloc") +@(objc_type=RenderPassStencilAttachmentDescriptor, objc_name="alloc", objc_is_class_method=true) RenderPassStencilAttachmentDescriptor_alloc :: #force_inline proc() -> ^RenderPassStencilAttachmentDescriptor { return msgSend(^RenderPassStencilAttachmentDescriptor, RenderPassStencilAttachmentDescriptor, "alloc") } @@ -3281,7 +3281,7 @@ Methods: @(objc_class="MTLRenderPipelineColorAttachmentDescriptor") RenderPipelineColorAttachmentDescriptor :: struct { using _: NS.Copying(RenderPipelineColorAttachmentDescriptor), using _: RenderPassAttachmentDescriptor } -@(objc_type=RenderPipelineColorAttachmentDescriptor, objc_class_name="alloc") +@(objc_type=RenderPipelineColorAttachmentDescriptor, objc_name="alloc", objc_is_class_method=true) RenderPipelineColorAttachmentDescriptor_alloc :: #force_inline proc() -> ^RenderPipelineColorAttachmentDescriptor { return msgSend(^RenderPipelineColorAttachmentDescriptor, RenderPipelineColorAttachmentDescriptor, "alloc") } @@ -3377,7 +3377,7 @@ Methods: @(objc_class="MTLRenderPipelineColorAttachmentDescriptorArray") RenderPipelineColorAttachmentDescriptorArray :: struct { using _: NS.Object } -@(objc_type=RenderPipelineColorAttachmentDescriptorArray, objc_class_name="alloc") +@(objc_type=RenderPipelineColorAttachmentDescriptorArray, objc_name="alloc", objc_is_class_method=true) RenderPipelineColorAttachmentDescriptorArray_alloc :: #force_inline proc() -> ^RenderPipelineColorAttachmentDescriptorArray { return msgSend(^RenderPipelineColorAttachmentDescriptorArray, RenderPipelineColorAttachmentDescriptorArray, "alloc") } @@ -3455,7 +3455,7 @@ Methods: @(objc_class="MTLRenderPipelineDescriptor") RenderPipelineDescriptor :: struct { using _: NS.Copying(RenderPipelineDescriptor) } -@(objc_type=RenderPipelineDescriptor, objc_class_name="alloc") +@(objc_type=RenderPipelineDescriptor, objc_name="alloc", objc_is_class_method=true) RenderPipelineDescriptor_alloc :: #force_inline proc() -> ^RenderPipelineDescriptor { return msgSend(^RenderPipelineDescriptor, RenderPipelineDescriptor, "alloc") } @@ -3672,7 +3672,7 @@ Methods: @(objc_class="MTLRenderPipelineReflection") RenderPipelineReflection :: struct { using _: NS.Object } -@(objc_type=RenderPipelineReflection, objc_class_name="alloc") +@(objc_type=RenderPipelineReflection, objc_name="alloc", objc_is_class_method=true) RenderPipelineReflection_alloc :: #force_inline proc() -> ^RenderPipelineReflection { return msgSend(^RenderPipelineReflection, RenderPipelineReflection, "alloc") } @@ -3708,7 +3708,7 @@ Methods: @(objc_class="MTLResourceStatePassDescriptor") ResourceStatePassDescriptor :: struct { using _: NS.Copying(ResourceStatePassDescriptor) } -@(objc_type=ResourceStatePassDescriptor, objc_class_name="alloc") +@(objc_type=ResourceStatePassDescriptor, objc_name="alloc", objc_is_class_method=true) ResourceStatePassDescriptor_alloc :: #force_inline proc() -> ^ResourceStatePassDescriptor { return msgSend(^ResourceStatePassDescriptor, ResourceStatePassDescriptor, "alloc") } @@ -3716,7 +3716,7 @@ ResourceStatePassDescriptor_alloc :: #force_inline proc() -> ^ResourceStatePassD ResourceStatePassDescriptor_init :: #force_inline proc(self: ^ResourceStatePassDescriptor) -> ^ResourceStatePassDescriptor { return msgSend(^ResourceStatePassDescriptor, self, "init") } -@(objc_type=ResourceStatePassDescriptor, objc_class_name="resourceStatePassDescriptor") +@(objc_type=ResourceStatePassDescriptor, objc_name="resourceStatePassDescriptor", objc_is_class_method=true) ResourceStatePassDescriptor_resourceStatePassDescriptor :: #force_inline proc() -> ^ResourceStatePassDescriptor { return msgSend(^ResourceStatePassDescriptor, ResourceStatePassDescriptor, "resourceStatePassDescriptor") } @@ -3744,7 +3744,7 @@ Methods: @(objc_class="MTLResourceStatePassSampleBufferAttachmentDescriptor") ResourceStatePassSampleBufferAttachmentDescriptor :: struct { using _: NS.Copying(ResourceStatePassSampleBufferAttachmentDescriptor) } -@(objc_type=ResourceStatePassSampleBufferAttachmentDescriptor, objc_class_name="alloc") +@(objc_type=ResourceStatePassSampleBufferAttachmentDescriptor, objc_name="alloc", objc_is_class_method=true) ResourceStatePassSampleBufferAttachmentDescriptor_alloc :: #force_inline proc() -> ^ResourceStatePassSampleBufferAttachmentDescriptor { return msgSend(^ResourceStatePassSampleBufferAttachmentDescriptor, ResourceStatePassSampleBufferAttachmentDescriptor, "alloc") } @@ -3792,7 +3792,7 @@ Methods: @(objc_class="MTLResourceStatePassSampleBufferAttachmentDescriptorArray") ResourceStatePassSampleBufferAttachmentDescriptorArray :: struct { using _: NS.Object } -@(objc_type=ResourceStatePassSampleBufferAttachmentDescriptorArray, objc_class_name="alloc") +@(objc_type=ResourceStatePassSampleBufferAttachmentDescriptorArray, objc_name="alloc", objc_is_class_method=true) ResourceStatePassSampleBufferAttachmentDescriptorArray_alloc :: #force_inline proc() -> ^ResourceStatePassSampleBufferAttachmentDescriptorArray { return msgSend(^ResourceStatePassSampleBufferAttachmentDescriptorArray, ResourceStatePassSampleBufferAttachmentDescriptorArray, "alloc") } @@ -3852,7 +3852,7 @@ Methods: @(objc_class="MTLSamplerDescriptor") SamplerDescriptor :: struct { using _: NS.Copying(SamplerDescriptor) } -@(objc_type=SamplerDescriptor, objc_class_name="alloc") +@(objc_type=SamplerDescriptor, objc_name="alloc", objc_is_class_method=true) SamplerDescriptor_alloc :: #force_inline proc() -> ^SamplerDescriptor { return msgSend(^SamplerDescriptor, SamplerDescriptor, "alloc") } @@ -3995,7 +3995,7 @@ Methods: @(objc_class="MTLSharedEventHandle") SharedEventHandle :: struct { using _: NS.Object } -@(objc_type=SharedEventHandle, objc_class_name="alloc") +@(objc_type=SharedEventHandle, objc_name="alloc", objc_is_class_method=true) SharedEventHandle_alloc :: #force_inline proc() -> ^SharedEventHandle { return msgSend(^SharedEventHandle, SharedEventHandle, "alloc") } @@ -4023,7 +4023,7 @@ Methods: @(objc_class="MTLSharedEventListener") SharedEventListener :: struct { using _: NS.Object } -@(objc_type=SharedEventListener, objc_class_name="alloc") +@(objc_type=SharedEventListener, objc_name="alloc", objc_is_class_method=true) SharedEventListener_alloc :: #force_inline proc() -> ^SharedEventListener { return msgSend(^SharedEventListener, SharedEventListener, "alloc") } @@ -4055,7 +4055,7 @@ Methods: @(objc_class="MTLSharedTextureHandle") SharedTextureHandle :: struct { using _: NS.Object } -@(objc_type=SharedTextureHandle, objc_class_name="alloc") +@(objc_type=SharedTextureHandle, objc_name="alloc", objc_is_class_method=true) SharedTextureHandle_alloc :: #force_inline proc() -> ^SharedTextureHandle { return msgSend(^SharedTextureHandle, SharedTextureHandle, "alloc") } @@ -4093,7 +4093,7 @@ Methods: @(objc_class="MTLStageInputOutputDescriptor") StageInputOutputDescriptor :: struct { using _: NS.Copying(StageInputOutputDescriptor) } -@(objc_type=StageInputOutputDescriptor, objc_class_name="alloc") +@(objc_type=StageInputOutputDescriptor, objc_name="alloc", objc_is_class_method=true) StageInputOutputDescriptor_alloc :: #force_inline proc() -> ^StageInputOutputDescriptor { return msgSend(^StageInputOutputDescriptor, StageInputOutputDescriptor, "alloc") } @@ -4129,7 +4129,7 @@ StageInputOutputDescriptor_setIndexBufferIndex :: #force_inline proc(self: ^Stag StageInputOutputDescriptor_setIndexType :: #force_inline proc(self: ^StageInputOutputDescriptor, indexType: IndexType) { msgSend(nil, self, "setIndexType:", indexType) } -@(objc_type=StageInputOutputDescriptor, objc_class_name="stageInputOutputDescriptor") +@(objc_type=StageInputOutputDescriptor, objc_name="stageInputOutputDescriptor", objc_is_class_method=true) StageInputOutputDescriptor_stageInputOutputDescriptor :: #force_inline proc() -> ^StageInputOutputDescriptor { return msgSend(^StageInputOutputDescriptor, StageInputOutputDescriptor, "stageInputOutputDescriptor") } @@ -4159,7 +4159,7 @@ Methods: @(objc_class="MTLStencilDescriptor") StencilDescriptor :: struct { using _: NS.Copying(StencilDescriptor) } -@(objc_type=StencilDescriptor, objc_class_name="alloc") +@(objc_type=StencilDescriptor, objc_name="alloc", objc_is_class_method=true) StencilDescriptor_alloc :: #force_inline proc() -> ^StencilDescriptor { return msgSend(^StencilDescriptor, StencilDescriptor, "alloc") } @@ -4237,7 +4237,7 @@ Methods: @(objc_class="MTLStructMember") StructMember :: struct { using _: NS.Object } -@(objc_type=StructMember, objc_class_name="alloc") +@(objc_type=StructMember, objc_name="alloc", objc_is_class_method=true) StructMember_alloc :: #force_inline proc() -> ^StructMember { return msgSend(^StructMember, StructMember, "alloc") } @@ -4293,7 +4293,7 @@ Methods: @(objc_class="MTLStructType") StructType :: struct { using _: Type } -@(objc_type=StructType, objc_class_name="alloc") +@(objc_type=StructType, objc_name="alloc", objc_is_class_method=true) StructType_alloc :: #force_inline proc() -> ^StructType { return msgSend(^StructType, StructType, "alloc") } @@ -4356,7 +4356,7 @@ Methods: @(objc_class="MTLTextureDescriptor") TextureDescriptor :: struct { using _: NS.Copying(TextureDescriptor) } -@(objc_type=TextureDescriptor, objc_class_name="alloc") +@(objc_type=TextureDescriptor, objc_name="alloc", objc_is_class_method=true) TextureDescriptor_alloc :: #force_inline proc() -> ^TextureDescriptor { return msgSend(^TextureDescriptor, TextureDescriptor, "alloc") } @@ -4472,15 +4472,15 @@ TextureDescriptor_storageMode :: #force_inline proc(self: ^TextureDescriptor) -> TextureDescriptor_swizzle :: #force_inline proc(self: ^TextureDescriptor) -> TextureSwizzleChannels { return msgSend(TextureSwizzleChannels, self, "swizzle") } -@(objc_type=TextureDescriptor, objc_class_name="texture2DDescriptor") +@(objc_type=TextureDescriptor, objc_name="texture2DDescriptor", objc_is_class_method=true) TextureDescriptor_texture2DDescriptor :: #force_inline proc(pixelFormat: PixelFormat, width: NS.UInteger, height: NS.UInteger, mipmapped: BOOL) -> ^TextureDescriptor { return msgSend(^TextureDescriptor, TextureDescriptor, "texture2DDescriptorWithPixelFormat:width:height:mipmapped:", pixelFormat, width, height, mipmapped) } -@(objc_type=TextureDescriptor, objc_class_name="textureBufferDescriptor") +@(objc_type=TextureDescriptor, objc_name="textureBufferDescriptor", objc_is_class_method=true) TextureDescriptor_textureBufferDescriptor :: #force_inline proc(pixelFormat: PixelFormat, width: NS.UInteger, resourceOptions: ResourceOptions, usage: TextureUsage) -> ^TextureDescriptor { return msgSend(^TextureDescriptor, TextureDescriptor, "textureBufferDescriptorWithPixelFormat:width:resourceOptions:usage:", pixelFormat, width, resourceOptions, usage) } -@(objc_type=TextureDescriptor, objc_class_name="textureCubeDescriptor") +@(objc_type=TextureDescriptor, objc_name="textureCubeDescriptor", objc_is_class_method=true) TextureDescriptor_textureCubeDescriptor :: #force_inline proc(pixelFormat: PixelFormat, size: NS.UInteger, mipmapped: BOOL) -> ^TextureDescriptor { return msgSend(^TextureDescriptor, TextureDescriptor, "textureCubeDescriptorWithPixelFormat:size:mipmapped:", pixelFormat, size, mipmapped) } @@ -4514,7 +4514,7 @@ Methods: @(objc_class="MTLTextureReferenceType") TextureReferenceType :: struct { using _: Type } -@(objc_type=TextureReferenceType, objc_class_name="alloc") +@(objc_type=TextureReferenceType, objc_name="alloc", objc_is_class_method=true) TextureReferenceType_alloc :: #force_inline proc() -> ^TextureReferenceType { return msgSend(^TextureReferenceType, TextureReferenceType, "alloc") } @@ -4554,7 +4554,7 @@ Methods: @(objc_class="MTLTileRenderPipelineColorAttachmentDescriptor") TileRenderPipelineColorAttachmentDescriptor :: struct { using _: NS.Copying(TileRenderPipelineColorAttachmentDescriptor) } -@(objc_type=TileRenderPipelineColorAttachmentDescriptor, objc_class_name="alloc") +@(objc_type=TileRenderPipelineColorAttachmentDescriptor, objc_name="alloc", objc_is_class_method=true) TileRenderPipelineColorAttachmentDescriptor_alloc :: #force_inline proc() -> ^TileRenderPipelineColorAttachmentDescriptor { return msgSend(^TileRenderPipelineColorAttachmentDescriptor, TileRenderPipelineColorAttachmentDescriptor, "alloc") } @@ -4586,7 +4586,7 @@ Methods: @(objc_class="MTLTileRenderPipelineColorAttachmentDescriptorArray") TileRenderPipelineColorAttachmentDescriptorArray :: struct { using _: NS.Object } -@(objc_type=TileRenderPipelineColorAttachmentDescriptorArray, objc_class_name="alloc") +@(objc_type=TileRenderPipelineColorAttachmentDescriptorArray, objc_name="alloc", objc_is_class_method=true) TileRenderPipelineColorAttachmentDescriptorArray_alloc :: #force_inline proc() -> ^TileRenderPipelineColorAttachmentDescriptorArray { return msgSend(^TileRenderPipelineColorAttachmentDescriptorArray, TileRenderPipelineColorAttachmentDescriptorArray, "alloc") } @@ -4631,7 +4631,7 @@ Methods: @(objc_class="MTLTileRenderPipelineDescriptor") TileRenderPipelineDescriptor :: struct { using _: NS.Copying(TileRenderPipelineDescriptor) } -@(objc_type=TileRenderPipelineDescriptor, objc_class_name="alloc") +@(objc_type=TileRenderPipelineDescriptor, objc_name="alloc", objc_is_class_method=true) TileRenderPipelineDescriptor_alloc :: #force_inline proc() -> ^TileRenderPipelineDescriptor { return msgSend(^TileRenderPipelineDescriptor, TileRenderPipelineDescriptor, "alloc") } @@ -4714,7 +4714,7 @@ Methods: @(objc_class="MTLType") Type :: struct { using _: NS.Object } -@(objc_type=Type, objc_class_name="alloc") +@(objc_type=Type, objc_name="alloc", objc_is_class_method=true) Type_alloc :: #force_inline proc() -> ^Type { return msgSend(^Type, Type, "alloc") } @@ -4746,7 +4746,7 @@ Methods: @(objc_class="MTLVertexAttribute") VertexAttribute :: struct { using _: NS.Object } -@(objc_type=VertexAttribute, objc_class_name="alloc") +@(objc_type=VertexAttribute, objc_name="alloc", objc_is_class_method=true) VertexAttribute_alloc :: #force_inline proc() -> ^VertexAttribute { return msgSend(^VertexAttribute, VertexAttribute, "alloc") } @@ -4798,7 +4798,7 @@ Methods: @(objc_class="MTLVertexAttributeDescriptor") VertexAttributeDescriptor :: struct { using _: NS.Copying(VertexAttributeDescriptor) } -@(objc_type=VertexAttributeDescriptor, objc_class_name="alloc") +@(objc_type=VertexAttributeDescriptor, objc_name="alloc", objc_is_class_method=true) VertexAttributeDescriptor_alloc :: #force_inline proc() -> ^VertexAttributeDescriptor { return msgSend(^VertexAttributeDescriptor, VertexAttributeDescriptor, "alloc") } @@ -4846,7 +4846,7 @@ Methods: @(objc_class="MTLVertexAttributeDescriptorArray") VertexAttributeDescriptorArray :: struct { using _: NS.Object } -@(objc_type=VertexAttributeDescriptorArray, objc_class_name="alloc") +@(objc_type=VertexAttributeDescriptorArray, objc_name="alloc", objc_is_class_method=true) VertexAttributeDescriptorArray_alloc :: #force_inline proc() -> ^VertexAttributeDescriptorArray { return msgSend(^VertexAttributeDescriptorArray, VertexAttributeDescriptorArray, "alloc") } @@ -4882,7 +4882,7 @@ Methods: @(objc_class="MTLVertexBufferLayoutDescriptor") VertexBufferLayoutDescriptor :: struct { using _: NS.Copying(VertexBufferLayoutDescriptor) } -@(objc_type=VertexBufferLayoutDescriptor, objc_class_name="alloc") +@(objc_type=VertexBufferLayoutDescriptor, objc_name="alloc", objc_is_class_method=true) VertexBufferLayoutDescriptor_alloc :: #force_inline proc() -> ^VertexBufferLayoutDescriptor { return msgSend(^VertexBufferLayoutDescriptor, VertexBufferLayoutDescriptor, "alloc") } @@ -4930,7 +4930,7 @@ Methods: @(objc_class="MTLVertexBufferLayoutDescriptorArray") VertexBufferLayoutDescriptorArray :: struct { using _: NS.Object } -@(objc_type=VertexBufferLayoutDescriptorArray, objc_class_name="alloc") +@(objc_type=VertexBufferLayoutDescriptorArray, objc_name="alloc", objc_is_class_method=true) VertexBufferLayoutDescriptorArray_alloc :: #force_inline proc() -> ^VertexBufferLayoutDescriptorArray { return msgSend(^VertexBufferLayoutDescriptorArray, VertexBufferLayoutDescriptorArray, "alloc") } @@ -4964,7 +4964,7 @@ Methods: @(objc_class="MTLVertexDescriptor") VertexDescriptor :: struct { using _: NS.Copying(VertexDescriptor) } -@(objc_type=VertexDescriptor, objc_class_name="alloc") +@(objc_type=VertexDescriptor, objc_name="alloc", objc_is_class_method=true) VertexDescriptor_alloc :: #force_inline proc() -> ^VertexDescriptor { return msgSend(^VertexDescriptor, VertexDescriptor, "alloc") } @@ -4984,7 +4984,7 @@ VertexDescriptor_layouts :: #force_inline proc(self: ^VertexDescriptor) -> ^Vert VertexDescriptor_reset :: #force_inline proc(self: ^VertexDescriptor) { msgSend(nil, self, "reset") } -@(objc_type=VertexDescriptor, objc_class_name="vertexDescriptor") +@(objc_type=VertexDescriptor, objc_name="vertexDescriptor", objc_is_class_method=true) VertexDescriptor_vertexDescriptor :: #force_inline proc() -> ^VertexDescriptor { return msgSend(^VertexDescriptor, VertexDescriptor, "vertexDescriptor") } @@ -5005,7 +5005,7 @@ Methods: @(objc_class="MTLVisibleFunctionTableDescriptor") VisibleFunctionTableDescriptor :: struct { using _: NS.Copying(VisibleFunctionTableDescriptor) } -@(objc_type=VisibleFunctionTableDescriptor, objc_class_name="alloc") +@(objc_type=VisibleFunctionTableDescriptor, objc_name="alloc", objc_is_class_method=true) VisibleFunctionTableDescriptor_alloc :: #force_inline proc() -> ^VisibleFunctionTableDescriptor { return msgSend(^VisibleFunctionTableDescriptor, VisibleFunctionTableDescriptor, "alloc") } @@ -5021,7 +5021,7 @@ VisibleFunctionTableDescriptor_functionCount :: #force_inline proc(self: ^Visibl VisibleFunctionTableDescriptor_setFunctionCount :: #force_inline proc(self: ^VisibleFunctionTableDescriptor, functionCount: NS.UInteger) { msgSend(nil, self, "setFunctionCount:", functionCount) } -@(objc_type=VisibleFunctionTableDescriptor, objc_class_name="visibleFunctionTableDescriptor") +@(objc_type=VisibleFunctionTableDescriptor, objc_name="visibleFunctionTableDescriptor", objc_is_class_method=true) VisibleFunctionTableDescriptor_visibleFunctionTableDescriptor :: #force_inline proc() -> ^VisibleFunctionTableDescriptor { return msgSend(^VisibleFunctionTableDescriptor, VisibleFunctionTableDescriptor, "visibleFunctionTableDescriptor") } @@ -7976,7 +7976,7 @@ Class: @(objc_class="MTLRenderPipelineFunctionsDescriptor") RenderPipelineFunctionsDescriptor :: struct { using _: NS.Copying(RenderPipelineFunctionsDescriptor) } -@(objc_type=RenderPipelineFunctionsDescriptor, objc_class_name="alloc") +@(objc_type=RenderPipelineFunctionsDescriptor, objc_name="alloc", objc_is_class_method=true) RenderPipelineFunctionsDescriptor_alloc :: #force_inline proc() -> ^RenderPipelineFunctionsDescriptor { return msgSend(^RenderPipelineFunctionsDescriptor, RenderPipelineFunctionsDescriptor, "alloc") } diff --git a/core/sys/darwin/QuartzCore/QuartzCore.odin b/core/sys/darwin/QuartzCore/QuartzCore.odin index 0afb8aa37..c35453efc 100644 --- a/core/sys/darwin/QuartzCore/QuartzCore.odin +++ b/core/sys/darwin/QuartzCore/QuartzCore.odin @@ -10,7 +10,7 @@ msgSend :: intrinsics.objc_send @(objc_class="CAMetalLayer") MetalLayer :: struct{ using _: NS.Layer} -@(objc_type=MetalLayer, objc_class_name="layer") +@(objc_type=MetalLayer, objc_name="layer", objc_is_class_method=true) MetalLayer_layer :: proc() -> ^MetalLayer { return msgSend(^MetalLayer, MetalLayer, "layer") } diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 1d30088d6..45d741532 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -826,15 +826,13 @@ void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) { } e->Procedure.optimization_mode = cast(ProcedureOptimizationMode)ac.optimization_mode; - if (ac.objc_name.len || ac.objc_class_name.len || ac.objc_type) { - if (ac.objc_class_name.len && ac.objc_name.len) { - error(e->token, "@(objc_class_name) and @(objc_name) may not be allowed at the same time"); + if (ac.objc_name.len || ac.objc_is_class_method || ac.objc_type) { + if (ac.objc_name.len == 0 && ac.objc_is_class_method) { + error(e->token, "@(objc_name) is required with @(objc_is_class_method)"); } else if (ac.objc_type == nullptr) { - if (ac.objc_name.len) { - error(e->token, "@(objc_name) requires that @(objc_type) to be set"); - } else { - error(e->token, "@(objc_class_name) requires that @(objc_type) to be set"); - } + error(e->token, "@(objc_name) requires that @(objc_type) to be set"); + } else if (ac.objc_name.len == 0 && ac.objc_type) { + error(e->token, "@(objc_name) is required with @(objc_type)"); } else { Type *t = ac.objc_type; if (t->kind == Type_Named) { @@ -843,7 +841,7 @@ void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) { GB_ASSERT(tn->kind == Entity_TypeName); if (tn->scope != e->scope) { - error(e->token, "@(objc_name) and @(objc_class_name) attributes may only be applied to procedures and types within the same scope"); + error(e->token, "@(objc_name) attribute may only be applied to procedures and types within the same scope"); } else { mutex_lock(&global_type_name_objc_metadata_mutex); defer (mutex_unlock(&global_type_name_objc_metadata_mutex)); @@ -855,7 +853,7 @@ void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) { mutex_lock(md->mutex); defer (mutex_unlock(md->mutex)); - if (ac.objc_name.len) { + if (!ac.objc_is_class_method) { bool ok = true; for (TypeNameObjCMetadataEntry const &entry : md->value_entries) { if (entry.name == ac.objc_name) { @@ -870,14 +868,14 @@ void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) { } else { bool ok = true; for (TypeNameObjCMetadataEntry const &entry : md->type_entries) { - if (entry.name == ac.objc_class_name) { - error(e->token, "Previous declaration of @(objc_class_name=\"%.*s\")", LIT(ac.objc_class_name)); + if (entry.name == ac.objc_name) { + error(e->token, "Previous declaration of @(objc_name=\"%.*s\")", LIT(ac.objc_name)); ok = false; break; } } if (ok) { - array_add(&md->type_entries, TypeNameObjCMetadataEntry{ac.objc_class_name, e}); + array_add(&md->type_entries, TypeNameObjCMetadataEntry{ac.objc_name, e}); } } } diff --git a/src/checker.cpp b/src/checker.cpp index 0dd36987e..dac4dd79f 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -3059,16 +3059,12 @@ DECL_ATTRIBUTE_PROC(proc_decl_attribute) { error(elem, "Expected a string value for '%.*s'", LIT(name)); } return true; - } else if (name == "objc_class_name") { + } else if (name == "objc_is_class_method") { ExactValue ev = check_decl_attribute_value(c, value); - if (ev.kind == ExactValue_String) { - if (string_is_valid_identifier(ev.value_string)) { - ac->objc_class_name = ev.value_string; - } else { - error(elem, "Invalid identifier for '%.*s', got '%.*s'", LIT(name), LIT(ev.value_string)); - } + if (ev.kind == ExactValue_Bool) { + ac->objc_is_class_method = ev.value_bool; } else { - error(elem, "Expected a string value for '%.*s'", LIT(name)); + error(elem, "Expected a boolean value for '%.*s'", LIT(name)); } return true; } else if (name == "objc_type") { diff --git a/src/checker.hpp b/src/checker.hpp index 38c8d32f6..552e6aca7 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -121,7 +121,7 @@ struct AttributeContext { String objc_class; String objc_name; - String objc_class_name; + bool objc_is_class_method; Type * objc_type; }; -- cgit v1.2.3 From 5f8137025d0abb946c186dc01271495cf839a871 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 18 Feb 2022 16:12:21 +0000 Subject: Use `try_to_add_package_dependency` --- src/check_builtin.cpp | 14 +++++++------- src/checker.cpp | 15 ++++++++++++++- 2 files changed, 21 insertions(+), 8 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index f440aa4d5..eb9d7f293 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -223,10 +223,10 @@ void add_objc_proc_type(CheckerContext *c, Ast *call, Type *return_type, Sliceinfo->objc_msgSend_types, call, data); mutex_unlock(&c->info->objc_types_mutex); - add_package_dependency(c, "runtime", "objc_msgSend"); - add_package_dependency(c, "runtime", "objc_msgSend_fpret"); - add_package_dependency(c, "runtime", "objc_msgSend_fp2ret"); - add_package_dependency(c, "runtime", "objc_msgSend_stret"); + try_to_add_package_dependency(c, "runtime", "objc_msgSend"); + try_to_add_package_dependency(c, "runtime", "objc_msgSend_fpret"); + try_to_add_package_dependency(c, "runtime", "objc_msgSend_fp2ret"); + try_to_add_package_dependency(c, "runtime", "objc_msgSend_stret"); } bool is_constant_string(CheckerContext *c, String const &builtin_name, Ast *expr, String *name_) { @@ -371,9 +371,9 @@ bool check_builtin_objc_procedure(CheckerContext *c, Operand *operand, Ast *call } operand->mode = Addressing_Value; - add_package_dependency(c, "runtime", "objc_lookUpClass"); - add_package_dependency(c, "runtime", "sel_registerName"); - add_package_dependency(c, "runtime", "objc_allocateClassPair"); + try_to_add_package_dependency(c, "runtime", "objc_lookUpClass"); + try_to_add_package_dependency(c, "runtime", "sel_registerName"); + try_to_add_package_dependency(c, "runtime", "objc_allocateClassPair"); return true; } break; } diff --git a/src/checker.cpp b/src/checker.cpp index 81e6f256e..f8aa8d45b 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -733,12 +733,25 @@ void add_package_dependency(CheckerContext *c, char const *package_name, char co String n = make_string_c(name); AstPackage *p = get_core_package(&c->checker->info, make_string_c(package_name)); Entity *e = scope_lookup(p->scope, n); - e->flags |= EntityFlag_Used; GB_ASSERT_MSG(e != nullptr, "%s", name); GB_ASSERT(c->decl != nullptr); + e->flags |= EntityFlag_Used; + add_dependency(c->info, c->decl, e); +} + +void try_to_add_package_dependency(CheckerContext *c, char const *package_name, char const *name) { + String n = make_string_c(name); + AstPackage *p = get_core_package(&c->checker->info, make_string_c(package_name)); + Entity *e = scope_lookup(p->scope, n); + if (e == nullptr) { + return; + } + GB_ASSERT(c->decl != nullptr); + e->flags |= EntityFlag_Used; add_dependency(c->info, c->decl, e); } + void add_declaration_dependency(CheckerContext *c, Entity *e) { if (e == nullptr) { return; -- cgit v1.2.3 From 71df46456a4db2592e8cebbdd4c46dc8b58b5a24 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 18 Feb 2022 21:30:25 +0000 Subject: Minimize memory usage by having an arena per thread rather than an arena per file --- src/array.cpp | 4 +++- src/checker.cpp | 4 ++-- src/common.cpp | 2 +- src/main.cpp | 2 +- src/parser.cpp | 12 ++++++------ src/parser.hpp | 6 ++---- 6 files changed, 15 insertions(+), 15 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/array.cpp b/src/array.cpp index ac3727978..d08bd647f 100644 --- a/src/array.cpp +++ b/src/array.cpp @@ -89,7 +89,9 @@ template void slice_init(Slice *s, gbAllocator const &allocator, isize count) { GB_ASSERT(count >= 0); s->data = gb_alloc_array(allocator, T, count); - GB_ASSERT(s->data != nullptr); + if (count > 0) { + GB_ASSERT(s->data != nullptr); + } s->count = count; } diff --git a/src/checker.cpp b/src/checker.cpp index f8aa8d45b..f440b7c9a 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -225,8 +225,8 @@ bool decl_info_has_init(DeclInfo *d) { Scope *create_scope(CheckerInfo *info, Scope *parent, isize init_elements_capacity=DEFAULT_SCOPE_CAPACITY) { Scope *s = gb_alloc_item(permanent_allocator(), Scope); s->parent = parent; - string_map_init(&s->elements, permanent_allocator(), init_elements_capacity); - ptr_set_init(&s->imported, permanent_allocator(), 0); + string_map_init(&s->elements, heap_allocator(), init_elements_capacity); + ptr_set_init(&s->imported, heap_allocator(), 0); mutex_init(&s->mutex); if (parent != nullptr && parent != builtin_pkg->scope) { diff --git a/src/common.cpp b/src/common.cpp index ab2a46118..d3ee95b76 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -1021,7 +1021,7 @@ LoadedFileError load_file_32(char const *fullpath, LoadedFile *memory_mapped_fil #endif } - gbFileContents fc = gb_file_read_contents(heap_allocator(), true, fullpath); + gbFileContents fc = gb_file_read_contents(permanent_allocator(), true, fullpath); if (fc.size > I32_MAX) { err = LoadedFile_FileTooLarge; diff --git a/src/main.cpp b/src/main.cpp index 014fbf822..291b56996 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2577,7 +2577,7 @@ int main(int arg_count, char const **arg_ptr) { // NOTE(bill): add 'shared' directory if it is not already set if (!find_library_collection_path(str_lit("shared"), nullptr)) { add_library_collection(str_lit("shared"), - get_fullpath_relative(heap_allocator(), odin_root_dir(), str_lit("shared"))); + get_fullpath_relative(heap_allocator(), odin_root_dir(), str_lit("shared"))); } diff --git a/src/parser.cpp b/src/parser.cpp index 7309d9769..8a7ab2d20 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -57,6 +57,9 @@ isize ast_node_size(AstKind kind) { return align_formula_isize(gb_size_of(AstCommonStuff) + ast_variant_sizes[kind], gb_align_of(void *)); } + +gb_global std::atomic global_total_node_memory_allocated; + // NOTE(bill): And this below is why is I/we need a new language! Discriminated unions are a pain in C/C++ Ast *alloc_ast_node(AstFile *f, AstKind kind) { gbAllocator a = ast_allocator(f); @@ -66,6 +69,9 @@ Ast *alloc_ast_node(AstFile *f, AstKind kind) { Ast *node = cast(Ast *)gb_alloc(a, size); node->kind = kind; node->file_id = f ? f->id : 0; + + global_total_node_memory_allocated += size; + return node; } @@ -4851,12 +4857,6 @@ ParseFileError init_ast_file(AstFile *f, String fullpath, TokenPos *err_pos) { f->prev_token = f->tokens[f->prev_token_index]; f->curr_token = f->tokens[f->curr_token_index]; - isize const page_size = 4*1024; - isize block_size = 2*f->tokens.count*gb_size_of(Ast); - block_size = ((block_size + page_size-1)/page_size) * page_size; - block_size = gb_clamp(block_size, page_size, DEFAULT_MINIMUM_BLOCK_SIZE); - f->arena.minimum_block_size = block_size; - array_init(&f->comments, heap_allocator(), 0, 0); array_init(&f->imports, heap_allocator(), 0, 0); diff --git a/src/parser.hpp b/src/parser.hpp index 83c755553..f6791a291 100644 --- a/src/parser.hpp +++ b/src/parser.hpp @@ -97,8 +97,6 @@ struct AstFile { AstPackage * pkg; Scope * scope; - Arena arena; - Ast * pkg_decl; String fullpath; Tokenizer tokenizer; @@ -801,10 +799,10 @@ gb_inline bool is_ast_when_stmt(Ast *node) { return node->kind == Ast_WhenStmt; } -gb_global gb_thread_local Arena global_ast_arena = {}; +gb_global gb_thread_local Arena global_thread_local_ast_arena = {}; gbAllocator ast_allocator(AstFile *f) { - Arena *arena = f ? &f->arena : &global_ast_arena; + Arena *arena = &global_thread_local_ast_arena; return arena_allocator(arena); } -- cgit v1.2.3 From 0fa487f468b1f63d5ec97ae8bbb0da01717f32cc Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 20 Feb 2022 14:27:44 +0000 Subject: Add `-foreign-error-procedures` --- core/runtime/error_checks.odin | 20 +++++++++++++++++++- src/build_settings.cpp | 2 ++ src/checker.cpp | 1 + src/main.cpp | 12 ++++++++++++ 4 files changed, 34 insertions(+), 1 deletion(-) (limited to 'src/checker.cpp') diff --git a/core/runtime/error_checks.odin b/core/runtime/error_checks.odin index 14d55c64c..ad6902e2d 100644 --- a/core/runtime/error_checks.odin +++ b/core/runtime/error_checks.odin @@ -17,6 +17,24 @@ type_assertion_trap :: proc "contextless" () -> ! { } +when ODIN_FOREIGN_ERROR_PROCEDURES { + foreign { + bounds_check_error :: proc "contextless" (file: string, line, column: i32, index, count: int) --- + slice_handle_error :: proc "contextless" (file: string, line, column: i32, lo, hi: int, len: int) -> ! --- + multi_pointer_slice_handle_error :: proc "contextless" (file: string, line, column: i32, lo, hi: int) -> ! --- + multi_pointer_slice_expr_error :: proc "contextless" (file: string, line, column: i32, lo, hi: int) --- + slice_expr_error_hi :: proc "contextless" (file: string, line, column: i32, hi: int, len: int) --- + slice_expr_error_lo_hi :: proc "contextless" (file: string, line, column: i32, lo, hi: int, len: int) --- + dynamic_array_expr_error :: proc "contextless" (file: string, line, column: i32, low, high, max: int) --- + matrix_bounds_check_error :: proc "contextless" (file: string, line, column: i32, row_index, column_index, row_count, column_count: int) --- + type_assertion_check :: proc "contextless" (ok: bool, file: string, line, column: i32, from, to: typeid) --- + type_assertion_check2 :: proc "contextless" (ok: bool, file: string, line, column: i32, from, to: typeid, from_data: rawptr) --- + make_slice_error_loc :: proc "contextless" (loc := #caller_location, len: int) --- + make_dynamic_array_error_loc :: proc "contextless" (using loc := #caller_location, len, cap: int) --- + make_map_expr_error_loc :: proc "contextless" (loc := #caller_location, cap: int) --- + } +} else { + bounds_check_error :: proc "contextless" (file: string, line, column: i32, index, count: int) { if 0 <= index && index < count { return @@ -231,7 +249,7 @@ make_map_expr_error_loc :: #force_inline proc "contextless" (loc := #caller_loca handle_error(loc, cap) } - +} diff --git a/src/build_settings.cpp b/src/build_settings.cpp index cc76f9e7c..cd9bdb40c 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -200,6 +200,7 @@ struct BuildContext { bool ODIN_DEBUG; // Odin in debug mode bool ODIN_DISABLE_ASSERT; // Whether the default 'assert' et al is disabled in code or not bool ODIN_DEFAULT_TO_NIL_ALLOCATOR; // Whether the default allocator is a "nil" allocator or not (i.e. it does nothing) + bool ODIN_FOREIGN_ERROR_PROCEDURES; ErrorPosStyle ODIN_ERROR_POS_STYLE; @@ -269,6 +270,7 @@ struct BuildContext { bool copy_file_contents; + u32 cmd_doc_flags; Array extra_packages; diff --git a/src/checker.cpp b/src/checker.cpp index f440b7c9a..fe1d362fa 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -976,6 +976,7 @@ void init_universal(void) { add_global_bool_constant("ODIN_USE_SEPARATE_MODULES", bc->use_separate_modules); add_global_bool_constant("ODIN_TEST", bc->command_kind == Command_test); add_global_bool_constant("ODIN_NO_ENTRY_POINT", bc->no_entry_point); + add_global_bool_constant("ODIN_FOREIGN_ERROR_PROCEDURES", bc->ODIN_FOREIGN_ERROR_PROCEDURES); // Builtin Procedures diff --git a/src/main.cpp b/src/main.cpp index 291b56996..5746ef146 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -632,6 +632,7 @@ enum BuildFlagKind { BuildFlag_InsertSemicolon, BuildFlag_StrictStyle, BuildFlag_StrictStyleInitOnly, + BuildFlag_ForeignErrorProcedures, BuildFlag_Compact, BuildFlag_GlobalDefinitions, @@ -785,10 +786,13 @@ bool parse_build_flags(Array args) { add_flag(&build_flags, BuildFlag_InsertSemicolon, str_lit("insert-semicolon"), BuildFlagParam_None, Command__does_check); add_flag(&build_flags, BuildFlag_StrictStyle, str_lit("strict-style"), BuildFlagParam_None, Command__does_check); add_flag(&build_flags, BuildFlag_StrictStyleInitOnly, str_lit("strict-style-init-only"), BuildFlagParam_None, Command__does_check); + add_flag(&build_flags, BuildFlag_ForeignErrorProcedures, str_lit("foreign-error-procedures"), 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); @@ -1356,6 +1360,9 @@ bool parse_build_flags(Array args) { case BuildFlag_DefaultToNilAllocator: build_context.ODIN_DEFAULT_TO_NIL_ALLOCATOR = true; break; + case BuildFlag_ForeignErrorProcedures: + build_context.ODIN_FOREIGN_ERROR_PROCEDURES = true; + break; case BuildFlag_InsertSemicolon: { gb_printf_err("-insert-semicolon flag is not required any more\n"); bad_flags = true; @@ -2084,6 +2091,11 @@ void print_show_help(String const arg0, String const &command) { print_usage_line(1, "-verbose-errors"); print_usage_line(2, "Prints verbose error messages showing the code on that line and the location in that line"); print_usage_line(0, ""); + + print_usage_line(1, "-foreign-error-procedures"); + print_usage_line(2, "States that the error procedues used in the runtime are defined in a separate translation unit"); + print_usage_line(0, ""); + } if (run_or_build) { -- cgit v1.2.3 From 493bc653b5762514dac8c8941d6564ccf5bb8528 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 23 Feb 2022 11:23:27 +0000 Subject: Add `@(no_red_zone)` for procedures --- src/check_decl.cpp | 8 ++++++++ src/checker.cpp | 7 +++++++ src/checker.hpp | 1 + src/entity.cpp | 1 + src/llvm_backend_proc.cpp | 4 ++++ 5 files changed, 21 insertions(+) (limited to 'src/checker.cpp') diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 45d741532..6f8caff98 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -826,6 +826,14 @@ void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) { } e->Procedure.optimization_mode = cast(ProcedureOptimizationMode)ac.optimization_mode; + if (ac.no_red_zone) { + if (!is_arch_wasm()) { + e->Procedure.no_red_zone = true; + } else { + error(e->token, "@(no_red_zone) is not supported on this target architecture"); + } + } + if (ac.objc_name.len || ac.objc_is_class_method || ac.objc_type) { if (ac.objc_name.len == 0 && ac.objc_is_class_method) { error(e->token, "@(objc_name) is required with @(objc_is_class_method)"); diff --git a/src/checker.cpp b/src/checker.cpp index fe1d362fa..89e60c258 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -3128,6 +3128,13 @@ DECL_ATTRIBUTE_PROC(proc_decl_attribute) { } } return true; + } else if (name == "no_red_zone") { + if (value != nullptr) { + error(elem, "Expected no value for '%.*s'", LIT(name)); + } else { + ac->no_red_zone = true; + } + return true; } return false; } diff --git a/src/checker.hpp b/src/checker.hpp index 552e6aca7..548439774 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -117,6 +117,7 @@ struct AttributeContext { bool test : 1; bool init : 1; bool set_cold : 1; + bool no_red_zone : 1; u32 optimization_mode; // ProcedureOptimizationMode String objc_class; diff --git a/src/entity.cpp b/src/entity.cpp index f5720293f..84ddd5c6b 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -226,6 +226,7 @@ struct Entity { bool is_foreign; bool is_export; bool generated_from_polymorphic; + bool no_red_zone; ProcedureOptimizationMode optimization_mode; } Procedure; struct { diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index 7ead77c2c..209f2f67b 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -135,6 +135,10 @@ lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool ignore_body) lb_add_attribute_to_proc(m, p->value, "naked"); } + if (entity->Procedure.no_red_zone) { + lb_add_attribute_to_proc(m, p->value, "noredzone"); + } + switch (p->inlining) { case ProcInlining_inline: lb_add_attribute_to_proc(m, p->value, "alwaysinline"); -- cgit v1.2.3 From 196bd735d4c30964182fdf1f374f767ccb0912fa Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 23 Feb 2022 11:29:36 +0000 Subject: Replace local `@(no_red_zone)` with global `-disable-red-zone` --- src/build_settings.cpp | 8 ++++++++ src/check_decl.cpp | 8 -------- src/checker.cpp | 7 ------- src/checker.hpp | 1 - src/entity.cpp | 1 - src/llvm_backend_proc.cpp | 2 +- src/main.cpp | 8 ++++++++ 7 files changed, 17 insertions(+), 18 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 790f7f1bc..62f43fad3 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -278,6 +278,7 @@ struct BuildContext { bool copy_file_contents; RelocMode reloc_mode; + bool disable_red_zone; u32 cmd_doc_flags; @@ -1002,6 +1003,13 @@ void init_build_context(TargetMetrics *cross_target) { bc->threaded_checker = true; #endif + if (bc->disable_red_zone) { + if (!(bc->metrics.os == TargetOs_freestanding && !is_arch_wasm())) { + gb_printf_err("-disable-red-zone is not support for this target"); + gb_exit(1); + } + } + // NOTE(zangent): The linker flags to set the build architecture are different // across OSs. It doesn't make sense to allocate extra data on the heap diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 6f8caff98..45d741532 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -826,14 +826,6 @@ void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) { } e->Procedure.optimization_mode = cast(ProcedureOptimizationMode)ac.optimization_mode; - if (ac.no_red_zone) { - if (!is_arch_wasm()) { - e->Procedure.no_red_zone = true; - } else { - error(e->token, "@(no_red_zone) is not supported on this target architecture"); - } - } - if (ac.objc_name.len || ac.objc_is_class_method || ac.objc_type) { if (ac.objc_name.len == 0 && ac.objc_is_class_method) { error(e->token, "@(objc_name) is required with @(objc_is_class_method)"); diff --git a/src/checker.cpp b/src/checker.cpp index 89e60c258..fe1d362fa 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -3128,13 +3128,6 @@ DECL_ATTRIBUTE_PROC(proc_decl_attribute) { } } return true; - } else if (name == "no_red_zone") { - if (value != nullptr) { - error(elem, "Expected no value for '%.*s'", LIT(name)); - } else { - ac->no_red_zone = true; - } - return true; } return false; } diff --git a/src/checker.hpp b/src/checker.hpp index 548439774..552e6aca7 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -117,7 +117,6 @@ struct AttributeContext { bool test : 1; bool init : 1; bool set_cold : 1; - bool no_red_zone : 1; u32 optimization_mode; // ProcedureOptimizationMode String objc_class; diff --git a/src/entity.cpp b/src/entity.cpp index 84ddd5c6b..f5720293f 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -226,7 +226,6 @@ struct Entity { bool is_foreign; bool is_export; bool generated_from_polymorphic; - bool no_red_zone; ProcedureOptimizationMode optimization_mode; } Procedure; struct { diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index 209f2f67b..053ee2fb2 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -135,7 +135,7 @@ lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool ignore_body) lb_add_attribute_to_proc(m, p->value, "naked"); } - if (entity->Procedure.no_red_zone) { + if (!entity->Procedure.is_foreign && build_context.disable_red_zone) { lb_add_attribute_to_proc(m, p->value, "noredzone"); } diff --git a/src/main.cpp b/src/main.cpp index cfc7decb1..1e7b78da4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -626,6 +626,7 @@ enum BuildFlagKind { BuildFlag_Microarch, BuildFlag_RelocMode, + BuildFlag_DisableRedZone, BuildFlag_TestName, @@ -782,6 +783,7 @@ bool parse_build_flags(Array args) { add_flag(&build_flags, BuildFlag_Microarch, str_lit("microarch"), BuildFlagParam_String, Command__does_build); add_flag(&build_flags, BuildFlag_RelocMode, str_lit("reloc-mode"), BuildFlagParam_String, Command__does_build); + add_flag(&build_flags, BuildFlag_DisableRedZone, str_lit("disable-red-zone"), BuildFlagParam_None, Command__does_build); add_flag(&build_flags, BuildFlag_TestName, str_lit("test-name"), BuildFlagParam_String, Command_test); @@ -1365,6 +1367,9 @@ bool parse_build_flags(Array args) { break; } + case BuildFlag_DisableRedZone: + build_context.disable_red_zone = true; + break; case BuildFlag_TestName: { GB_ASSERT(value.kind == ExactValue_String); { @@ -2096,6 +2101,9 @@ void print_show_help(String const arg0, String const &command) { print_usage_line(3, "pic"); print_usage_line(3, "dynamic-no-pic"); print_usage_line(0, ""); + + print_usage_line(1, "-disable-red-zone"); + print_usage_line(2, "Disable red zone on a supported freestanding target"); } if (check) { -- cgit v1.2.3 From 5676c9e7ebcec9af526c59ece1faf2e8b15e457c Mon Sep 17 00:00:00 2001 From: Sébastien Marie Date: Fri, 25 Feb 2022 08:49:25 +0000 Subject: initial OpenBSD support --- Makefile | 6 + core/c/libc/errno.odin | 13 + core/c/libc/stdio.odin | 25 ++ core/c/libc/time.odin | 9 +- core/c/libc/wctype.odin | 5 + core/crypto/rand_generic.odin | 2 +- core/crypto/rand_openbsd.odin | 12 + core/dynlib/lib_unix.odin | 2 +- core/os/dir_openbsd.odin | 71 ++++ core/os/os_openbsd.odin | 706 +++++++++++++++++++++++++++++++ core/os/stat_unix.odin | 2 +- core/path/filepath/path_unix.odin | 7 +- core/runtime/entry_unix.odin | 2 +- core/sync/channel_unix.odin | 2 +- core/sync/sync2/futex_openbsd.odin | 78 ++++ core/sync/sync2/primitives_openbsd.odin | 9 + core/sync/sync2/primitives_pthreads.odin | 2 +- core/sync/sync_openbsd.odin | 36 ++ core/sync/sync_unix.odin | 2 +- core/sys/unix/pthread_openbsd.odin | 65 +++ core/sys/unix/pthread_unix.odin | 2 +- core/thread/thread_unix.odin | 2 +- core/time/time_unix.odin | 34 +- src/bug_report.cpp | 14 +- src/build_settings.cpp | 18 + src/check_builtin.cpp | 1 + src/checker.cpp | 1 + src/common.cpp | 2 +- src/gb/gb.h | 46 +- src/threading.cpp | 2 +- 30 files changed, 1151 insertions(+), 27 deletions(-) create mode 100644 core/crypto/rand_openbsd.odin create mode 100644 core/os/dir_openbsd.odin create mode 100644 core/os/os_openbsd.odin create mode 100644 core/sync/sync2/futex_openbsd.odin create mode 100644 core/sync/sync2/primitives_openbsd.odin create mode 100644 core/sync/sync_openbsd.odin create mode 100644 core/sys/unix/pthread_openbsd.odin (limited to 'src/checker.cpp') diff --git a/Makefile b/Makefile index d3d3c6a2d..99c71ccd9 100644 --- a/Makefile +++ b/Makefile @@ -58,6 +58,12 @@ ifeq ($(OS), Linux) CFLAGS:=$(CFLAGS) $(shell $(LLVM_CONFIG) --cxxflags --ldflags) LDFLAGS:=$(LDFLAGS) $(shell $(LLVM_CONFIG) --libs core native --system-libs) endif +ifeq ($(OS), OpenBSD) + LLVM_CONFIG=/usr/local/bin/llvm-config + + CFLAGS:=$(CFLAGS) $(shell $(LLVM_CONFIG) --cxxflags --ldflags) + LDFLAGS:=$(LDFLAGS) -liconv $(shell $(LLVM_CONFIG) --libs core native --system-libs) +endif all: debug demo diff --git a/core/c/libc/errno.odin b/core/c/libc/errno.odin index ecde6af59..53437f42f 100644 --- a/core/c/libc/errno.odin +++ b/core/c/libc/errno.odin @@ -27,6 +27,19 @@ when ODIN_OS == .Linux || ODIN_OS == .FreeBSD { ERANGE :: 34 } +when ODIN_OS == .OpenBSD { + @(private="file") + @(default_calling_convention="c") + foreign libc { + @(link_name="__errno") + _get_errno :: proc() -> ^int --- + } + + EDOM :: 33 + EILSEQ :: 84 + ERANGE :: 34 +} + when ODIN_OS == .Windows { @(private="file") @(default_calling_convention="c") diff --git a/core/c/libc/stdio.odin b/core/c/libc/stdio.odin index 9c4a1a708..fc65b954a 100644 --- a/core/c/libc/stdio.odin +++ b/core/c/libc/stdio.odin @@ -78,6 +78,31 @@ when ODIN_OS == .Linux { } } +when ODIN_OS == .OpenBSD { + fpos_t :: i64 + + _IOFBF :: 0 + _IOLBF :: 1 + _IONBF :: 1 + + BUFSIZ :: 1024 + + EOF :: int(-1) + + FOPEN_MAX :: 20 + FILENAME_MAX :: 1024 + + SEEK_SET :: 0 + SEEK_CUR :: 1 + SEEK_END :: 2 + + foreign libc { + stderr: ^FILE + stdin: ^FILE + stdout: ^FILE + } +} + when ODIN_OS == .Darwin { fpos_t :: distinct i64 diff --git a/core/c/libc/time.odin b/core/c/libc/time.odin index b3539a227..b337e139a 100644 --- a/core/c/libc/time.odin +++ b/core/c/libc/time.odin @@ -45,7 +45,7 @@ when ODIN_OS == .Windows { } } -when ODIN_OS == .Linux || ODIN_OS == .FreeBSD || ODIN_OS == .Darwin { +when ODIN_OS == .Linux || ODIN_OS == .FreeBSD || ODIN_OS == .Darwin || ODIN_OS == .OpenBSD { @(default_calling_convention="c") foreign libc { // 7.27.2 Time manipulation functions @@ -63,7 +63,12 @@ when ODIN_OS == .Linux || ODIN_OS == .FreeBSD || ODIN_OS == .Darwin { strftime :: proc(s: [^]char, maxsize: size_t, format: cstring, timeptr: ^tm) -> size_t --- } - CLOCKS_PER_SEC :: 1000000 + when ODIN_OS == .OpenBSD { + CLOCKS_PER_SEC :: 100 + } else { + CLOCKS_PER_SEC :: 1000000 + } + TIME_UTC :: 1 time_t :: distinct i64 diff --git a/core/c/libc/wctype.odin b/core/c/libc/wctype.odin index 942726ba6..f833af51f 100644 --- a/core/c/libc/wctype.odin +++ b/core/c/libc/wctype.odin @@ -25,6 +25,11 @@ when ODIN_OS == .Darwin { wctype_t :: distinct u32 } +when ODIN_OS == .OpenBSD { + wctrans_t :: distinct rawptr + wctype_t :: distinct rawptr +} + @(default_calling_convention="c") foreign libc { // 7.30.2.1 Wide character classification functions diff --git a/core/crypto/rand_generic.odin b/core/crypto/rand_generic.odin index be6987ee2..10edc1c8a 100644 --- a/core/crypto/rand_generic.odin +++ b/core/crypto/rand_generic.odin @@ -1,6 +1,6 @@ package crypto -when ODIN_OS != .Linux { +when ODIN_OS != .Linux && ODIN_OS != .OpenBSD { _rand_bytes :: proc (dst: []byte) { unimplemented("crypto: rand_bytes not supported on this OS") } diff --git a/core/crypto/rand_openbsd.odin b/core/crypto/rand_openbsd.odin new file mode 100644 index 000000000..bae97e8f0 --- /dev/null +++ b/core/crypto/rand_openbsd.odin @@ -0,0 +1,12 @@ +package crypto + +import "core:c" + +foreign import libc "system:c" +foreign libc { + arc4random_buf :: proc "c" (buf: rawptr, nbytes: c.size_t) --- +} + +_rand_bytes :: proc (dst: []byte) { + arc4random_buf(raw_data(dst), len(dst)) +} diff --git a/core/dynlib/lib_unix.odin b/core/dynlib/lib_unix.odin index bb8affb79..e52ade153 100644 --- a/core/dynlib/lib_unix.odin +++ b/core/dynlib/lib_unix.odin @@ -1,4 +1,4 @@ -// +build linux, darwin, freebsd +// +build linux, darwin, freebsd, openbsd package dynlib import "core:os" diff --git a/core/os/dir_openbsd.odin b/core/os/dir_openbsd.odin new file mode 100644 index 000000000..465fd35ae --- /dev/null +++ b/core/os/dir_openbsd.odin @@ -0,0 +1,71 @@ +package os + +import "core:strings" +import "core:mem" + +read_dir :: proc(fd: Handle, n: int, allocator := context.allocator) -> (fi: []File_Info, err: Errno) { + dirp: Dir + dirp, err = _fdopendir(fd) + if err != ERROR_NONE { + return + } + + defer _closedir(dirp) + + // XXX OpenBSD + dirpath: string + dirpath, err = absolute_path_from_handle(fd) + + if err != ERROR_NONE { + return + } + + defer delete(dirpath) + + n := n + size := n + if n <= 0 { + n = -1 + size = 100 + } + + dfi := make([dynamic]File_Info, 0, size, allocator) + + for { + entry: Dirent + end_of_stream: bool + entry, err, end_of_stream = _readdir(dirp) + if err != ERROR_NONE { + for fi_ in dfi { + file_info_delete(fi_, allocator) + } + delete(dfi) + return + } else if end_of_stream { + break + } + + fi_: File_Info + filename := cast(string)(transmute(cstring)mem.Raw_Cstring{ data = &entry.name[0] }) + + if filename == "." || filename == ".." { + continue + } + + fullpath := strings.join( []string{ dirpath, filename }, "/", context.temp_allocator) + defer delete(fullpath, context.temp_allocator) + + fi_, err = stat(fullpath, allocator) + if err != ERROR_NONE { + for fi__ in dfi { + file_info_delete(fi__, allocator) + } + delete(dfi) + return + } + + append(&dfi, fi_) + } + + return dfi[:], ERROR_NONE +} diff --git a/core/os/os_openbsd.odin b/core/os/os_openbsd.odin new file mode 100644 index 000000000..3862851a1 --- /dev/null +++ b/core/os/os_openbsd.odin @@ -0,0 +1,706 @@ +package os + +foreign import libc "system:c" + +import "core:runtime" +import "core:strings" +import "core:c" + +Handle :: distinct i32 +Pid :: distinct i32 +File_Time :: distinct u64 +Errno :: distinct i32 + +INVALID_HANDLE :: ~Handle(0) + +ERROR_NONE: Errno: 0 + +EPERM: Errno: 1 +ENOENT: Errno: 2 +ESRCH: Errno: 3 +EINTR: Errno: 4 +EIO: Errno: 5 +ENXIO: Errno: 6 +E2BIG: Errno: 7 +ENOEXEC: Errno: 8 +EBADF: Errno: 9 +ECHILD: Errno: 10 +EDEADLK: Errno: 11 +ENOMEM: Errno: 12 +EACCES: Errno: 13 +EFAULT: Errno: 14 +ENOTBLK: Errno: 15 +EBUSY: Errno: 16 +EEXIST: Errno: 17 +EXDEV: Errno: 18 +ENODEV: Errno: 19 +ENOTDIR: Errno: 20 +EISDIR: Errno: 21 +EINVAL: Errno: 22 +ENFILE: Errno: 23 +EMFILE: Errno: 24 +ENOTTY: Errno: 25 +ETXTBSY: Errno: 26 +EFBIG: Errno: 27 +ENOSPC: Errno: 28 +ESPIPE: Errno: 29 +EROFS: Errno: 30 +EMLINK: Errno: 31 +EPIPE: Errno: 32 +EDOM: Errno: 33 +ERANGE: Errno: 34 +EAGAIN: Errno: 35 +EWOULDBLOCK: Errno: EAGAIN +EINPROGRESS: Errno: 36 +EALREADY: Errno: 37 +ENOTSOCK: Errno: 38 +EDESTADDRREQ: Errno: 39 +EMSGSIZE: Errno: 40 +EPROTOTYPE: Errno: 41 +ENOPROTOOPT: Errno: 42 +EPROTONOSUPPORT: Errno: 43 +ESOCKTNOSUPPORT: Errno: 44 +EOPNOTSUPP: Errno: 45 +EPFNOSUPPORT: Errno: 46 +EAFNOSUPPORT: Errno: 47 +EADDRINUSE: Errno: 48 +EADDRNOTAVAIL: Errno: 49 +ENETDOWN: Errno: 50 +ENETUNREACH: Errno: 51 +ENETRESET: Errno: 52 +ECONNABORTED: Errno: 53 +ECONNRESET: Errno: 54 +ENOBUFS: Errno: 55 +EISCONN: Errno: 56 +ENOTCONN: Errno: 57 +ESHUTDOWN: Errno: 58 +ETOOMANYREFS: Errno: 59 +ETIMEDOUT: Errno: 60 +ECONNREFUSED: Errno: 61 +ELOOP: Errno: 62 +ENAMETOOLONG: Errno: 63 +EHOSTDOWN: Errno: 64 +EHOSTUNREACH: Errno: 65 +ENOTEMPTY: Errno: 66 +EPROCLIM: Errno: 67 +EUSERS: Errno: 68 +EDQUOT: Errno: 69 +ESTALE: Errno: 70 +EREMOTE: Errno: 71 +EBADRPC: Errno: 72 +ERPCMISMATCH: Errno: 73 +EPROGUNAVAIL: Errno: 74 +EPROGMISMATCH: Errno: 75 +EPROCUNAVAIL: Errno: 76 +ENOLCK: Errno: 77 +ENOSYS: Errno: 78 +EFTYPE: Errno: 79 +EAUTH: Errno: 80 +ENEEDAUTH: Errno: 81 +EIPSEC: Errno: 82 +ENOATTR: Errno: 83 +EILSEQ: Errno: 84 +ENOMEDIUM: Errno: 85 +EMEDIUMTYPE: Errno: 86 +EOVERFLOW: Errno: 87 +ECANCELED: Errno: 88 +EIDRM: Errno: 89 +ENOMSG: Errno: 90 +ENOTSUP: Errno: 91 +EBADMSG: Errno: 92 +ENOTRECOVERABLE: Errno: 93 +EOWNERDEAD: Errno: 94 +EPROTO: Errno: 95 + +O_RDONLY :: 0x00000 +O_WRONLY :: 0x00001 +O_RDWR :: 0x00002 +O_NONBLOCK :: 0x00004 +O_APPEND :: 0x00008 +O_ASYNC :: 0x00040 +O_SYNC :: 0x00080 +O_CREATE :: 0x00200 +O_TRUNC :: 0x00400 +O_EXCL :: 0x00800 +O_NOCTTY :: 0x08000 +O_CLOEXEC :: 0x10000 + +SEEK_SET :: 0 +SEEK_CUR :: 1 +SEEK_END :: 2 + +RTLD_LAZY :: 0x001 +RTLD_NOW :: 0x002 +RTLD_LOCAL :: 0x000 +RTLD_GLOBAL :: 0x100 +RTLD_TRACE :: 0x200 +RTLD_NODELETE :: 0x400 + +MAX_PATH :: 1024 + +// "Argv" arguments converted to Odin strings +args := _alloc_command_line_arguments() + +pid_t :: i32 +time_t :: i64 +mode_t :: u32 +dev_t :: i32 +ino_t :: u64 +nlink_t :: u32 +uid_t :: u32 +gid_t :: u32 +off_t :: i64 +blkcnt_t :: u64 +blksize_t :: i32 + +Unix_File_Time :: struct { + seconds: time_t, + nanoseconds: c.long, +} + +OS_Stat :: struct { + mode: mode_t, // inode protection mode + device_id: dev_t, // inode's device + serial: ino_t, // inode's number + nlink: nlink_t, // number of hard links + uid: uid_t, // user ID of the file's owner + gid: gid_t, // group ID of the file's group + rdev: dev_t, // device type + + last_access: Unix_File_Time, // time of last access + modified: Unix_File_Time, // time of last data modification + status_change: Unix_File_Time, // time of last file status change + + size: off_t, // file size, in bytes + blocks: blkcnt_t, // blocks allocated for file + block_size: blksize_t, // optimal blocksize for I/O + + flags: u32, // user defined flags for file + gen: u32, // file generation number + birthtime: Unix_File_Time, // time of file creation +} + +MAXNAMLEN :: 255 + +// NOTE(laleksic, 2021-01-21): Comment and rename these to match OS_Stat above +Dirent :: struct { + ino: ino_t, // file number of entry + off: off_t, // offset after this entry + reclen: u16, // length of this record + type: u8, // file type + namlen: u8, // length of string in name + _padding: [4]u8, + name: [MAXNAMLEN + 1]byte, // name +} + +Dir :: distinct rawptr // DIR* + +// File type +S_IFMT :: 0o170000 // Type of file mask +S_IFIFO :: 0o010000 // Named pipe (fifo) +S_IFCHR :: 0o020000 // Character special +S_IFDIR :: 0o040000 // Directory +S_IFBLK :: 0o060000 // Block special +S_IFREG :: 0o100000 // Regular +S_IFLNK :: 0o120000 // Symbolic link +S_IFSOCK :: 0o140000 // Socket +S_ISVTX :: 0o001000 // Save swapped text even after use + +// File mode + // Read, write, execute/search by owner +S_IRWXU :: 0o0700 // RWX mask for owner +S_IRUSR :: 0o0400 // R for owner +S_IWUSR :: 0o0200 // W for owner +S_IXUSR :: 0o0100 // X for owner + + // Read, write, execute/search by group +S_IRWXG :: 0o0070 // RWX mask for group +S_IRGRP :: 0o0040 // R for group +S_IWGRP :: 0o0020 // W for group +S_IXGRP :: 0o0010 // X for group + + // Read, write, execute/search by others +S_IRWXO :: 0o0007 // RWX mask for other +S_IROTH :: 0o0004 // R for other +S_IWOTH :: 0o0002 // W for other +S_IXOTH :: 0o0001 // X for other + +S_ISUID :: 0o4000 // Set user id on execution +S_ISGID :: 0o2000 // Set group id on execution +S_ISTXT :: 0o1000 // Sticky bit + +S_ISLNK :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFLNK } +S_ISREG :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFREG } +S_ISDIR :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFDIR } +S_ISCHR :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFCHR } +S_ISBLK :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFBLK } +S_ISFIFO :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFIFO } +S_ISSOCK :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFSOCK } + +F_OK :: 0x00 // Test for file existance +X_OK :: 0x01 // Test for execute permission +W_OK :: 0x02 // Test for write permission +R_OK :: 0x04 // Test for read permission + +AT_FDCWD :: -100 +AT_EACCESS :: 0x01 +AT_SYMLINK_NOFOLLOW :: 0x02 +AT_SYMLINK_FOLLOW :: 0x04 +AT_REMOVEDIR :: 0x08 + +@(default_calling_convention="c") +foreign libc { + @(link_name="__errno") __errno :: proc() -> ^int --- + + @(link_name="fork") _unix_fork :: proc() -> pid_t --- + @(link_name="getthrid") _unix_getthrid :: proc() -> int --- + + @(link_name="open") _unix_open :: proc(path: cstring, flags: c.int, mode: c.int) -> Handle --- + @(link_name="close") _unix_close :: proc(fd: Handle) -> c.int --- + @(link_name="read") _unix_read :: proc(fd: Handle, buf: rawptr, size: c.size_t) -> c.ssize_t --- + @(link_name="write") _unix_write :: proc(fd: Handle, buf: rawptr, size: c.size_t) -> c.ssize_t --- + @(link_name="lseek") _unix_seek :: proc(fd: Handle, offset: off_t, whence: c.int) -> off_t --- + @(link_name="stat") _unix_stat :: proc(path: cstring, sb: ^OS_Stat) -> c.int --- + @(link_name="fstat") _unix_fstat :: proc(fd: Handle, sb: ^OS_Stat) -> c.int --- + @(link_name="lstat") _unix_lstat :: proc(path: cstring, sb: ^OS_Stat) -> c.int --- + @(link_name="readlink") _unix_readlink :: proc(path: cstring, buf: ^byte, bufsiz: c.size_t) -> c.ssize_t --- + @(link_name="access") _unix_access :: proc(path: cstring, mask: c.int) -> c.int --- + @(link_name="getcwd") _unix_getcwd :: proc(buf: cstring, len: c.size_t) -> cstring --- + @(link_name="chdir") _unix_chdir :: proc(path: cstring) -> c.int --- + @(link_name="rename") _unix_rename :: proc(old, new: cstring) -> c.int --- + @(link_name="unlink") _unix_unlink :: proc(path: cstring) -> c.int --- + @(link_name="rmdir") _unix_rmdir :: proc(path: cstring) -> c.int --- + @(link_name="mkdir") _unix_mkdir :: proc(path: cstring, mode: mode_t) -> c.int --- + + @(link_name="getpagesize") _unix_getpagesize :: proc() -> c.int --- + @(link_name="fdopendir") _unix_fdopendir :: proc(fd: Handle) -> Dir --- + @(link_name="closedir") _unix_closedir :: proc(dirp: Dir) -> c.int --- + @(link_name="rewinddir") _unix_rewinddir :: proc(dirp: Dir) --- + @(link_name="readdir_r") _unix_readdir_r :: proc(dirp: Dir, entry: ^Dirent, result: ^^Dirent) -> c.int --- + + @(link_name="malloc") _unix_malloc :: proc(size: c.size_t) -> rawptr --- + @(link_name="calloc") _unix_calloc :: proc(num, size: c.size_t) -> rawptr --- + @(link_name="free") _unix_free :: proc(ptr: rawptr) --- + @(link_name="realloc") _unix_realloc :: proc(ptr: rawptr, size: c.size_t) -> rawptr --- + + @(link_name="getenv") _unix_getenv :: proc(cstring) -> cstring --- + @(link_name="realpath") _unix_realpath :: proc(path: cstring, resolved_path: rawptr) -> rawptr --- + + @(link_name="exit") _unix_exit :: proc(status: c.int) -> ! --- + + @(link_name="dlopen") _unix_dlopen :: proc(filename: cstring, flags: c.int) -> rawptr --- + @(link_name="dlsym") _unix_dlsym :: proc(handle: rawptr, symbol: cstring) -> rawptr --- + @(link_name="dlclose") _unix_dlclose :: proc(handle: rawptr) -> c.int --- + @(link_name="dlerror") _unix_dlerror :: proc() -> cstring --- +} + +is_path_separator :: proc(r: rune) -> bool { + return r == '/' +} + +get_last_error :: proc() -> int { + return __errno()^ +} + +fork :: proc() -> (Pid, Errno) { + pid := _unix_fork() + if pid == -1 { + return Pid(-1), Errno(get_last_error()) + } + return Pid(pid), ERROR_NONE +} + +open :: proc(path: string, flags: int = O_RDONLY, mode: int = 0) -> (Handle, Errno) { + cstr := strings.clone_to_cstring(path, context.temp_allocator) + handle := _unix_open(cstr, c.int(flags), c.int(mode)) + if handle == -1 { + return INVALID_HANDLE, Errno(get_last_error()) + } + return handle, ERROR_NONE +} + +close :: proc(fd: Handle) -> Errno { + result := _unix_close(fd) + if result == -1 { + return Errno(get_last_error()) + } + return ERROR_NONE +} + +read :: proc(fd: Handle, data: []byte) -> (int, Errno) { + bytes_read := _unix_read(fd, &data[0], c.size_t(len(data))) + if bytes_read == -1 { + return -1, Errno(get_last_error()) + } + return int(bytes_read), ERROR_NONE +} + +write :: proc(fd: Handle, data: []byte) -> (int, Errno) { + if len(data) == 0 { + return 0, ERROR_NONE + } + bytes_written := _unix_write(fd, &data[0], c.size_t(len(data))) + if bytes_written == -1 { + return -1, Errno(get_last_error()) + } + return int(bytes_written), ERROR_NONE +} + +seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Errno) { + res := _unix_seek(fd, offset, c.int(whence)) + if res == -1 { + return -1, Errno(get_last_error()) + } + return res, ERROR_NONE +} + +file_size :: proc(fd: Handle) -> (i64, Errno) { + s, err := _fstat(fd) + if err != ERROR_NONE { + return -1, err + } + return s.size, ERROR_NONE +} + +rename :: proc(old_path, new_path: string) -> Errno { + old_path_cstr := strings.clone_to_cstring(old_path, context.temp_allocator) + new_path_cstr := strings.clone_to_cstring(new_path, context.temp_allocator) + res := _unix_rename(old_path_cstr, new_path_cstr) + if res == -1 { + return Errno(get_last_error()) + } + return ERROR_NONE +} + +remove :: proc(path: string) -> Errno { + path_cstr := strings.clone_to_cstring(path, context.temp_allocator) + res := _unix_unlink(path_cstr) + if res == -1 { + return Errno(get_last_error()) + } + return ERROR_NONE +} + +make_directory :: proc(path: string, mode: mode_t = 0o775) -> Errno { + path_cstr := strings.clone_to_cstring(path, context.temp_allocator) + res := _unix_mkdir(path_cstr, mode) + if res == -1 { + return Errno(get_last_error()) + } + return ERROR_NONE +} + +remove_directory :: proc(path: string) -> Errno { + path_cstr := strings.clone_to_cstring(path, context.temp_allocator) + res := _unix_rmdir(path_cstr) + if res == -1 { + return Errno(get_last_error()) + } + return ERROR_NONE +} + +is_file_handle :: proc(fd: Handle) -> bool { + s, err := _fstat(fd) + if err != ERROR_NONE { + return false + } + return S_ISREG(s.mode) +} + +is_file_path :: proc(path: string, follow_links: bool = true) -> bool { + s: OS_Stat + err: Errno + if follow_links { + s, err = _stat(path) + } else { + s, err = _lstat(path) + } + if err != ERROR_NONE { + return false + } + return S_ISREG(s.mode) +} + +is_dir_handle :: proc(fd: Handle) -> bool { + s, err := _fstat(fd) + if err != ERROR_NONE { + return false + } + return S_ISDIR(s.mode) +} + +is_dir_path :: proc(path: string, follow_links: bool = true) -> bool { + s: OS_Stat + err: Errno + if follow_links { + s, err = _stat(path) + } else { + s, err = _lstat(path) + } + if err != ERROR_NONE { + return false + } + return S_ISDIR(s.mode) +} + +is_file :: proc {is_file_path, is_file_handle} +is_dir :: proc {is_dir_path, is_dir_handle} + +// NOTE(bill): Uses startup to initialize it + +stdin: Handle = 0 +stdout: Handle = 1 +stderr: Handle = 2 + +/* TODO(zangent): Implement these! +last_write_time :: proc(fd: Handle) -> File_Time {} +last_write_time_by_name :: proc(name: string) -> File_Time {} +*/ +last_write_time :: proc(fd: Handle) -> (File_Time, Errno) { + s, err := _fstat(fd) + if err != ERROR_NONE { + return 0, err + } + modified := s.modified.seconds * 1_000_000_000 + s.modified.nanoseconds + return File_Time(modified), ERROR_NONE +} + +last_write_time_by_name :: proc(name: string) -> (File_Time, Errno) { + s, err := _stat(name) + if err != ERROR_NONE { + return 0, err + } + modified := s.modified.seconds * 1_000_000_000 + s.modified.nanoseconds + return File_Time(modified), ERROR_NONE +} + +@private +_stat :: proc(path: string) -> (OS_Stat, Errno) { + cstr := strings.clone_to_cstring(path, context.temp_allocator) + + // deliberately uninitialized + s: OS_Stat = --- + res := _unix_stat(cstr, &s) + if res == -1 { + return s, Errno(get_last_error()) + } + return s, ERROR_NONE +} + +@private +_lstat :: proc(path: string) -> (OS_Stat, Errno) { + cstr := strings.clone_to_cstring(path, context.temp_allocator) + + // deliberately uninitialized + s: OS_Stat = --- + res := _unix_lstat(cstr, &s) + if res == -1 { + return s, Errno(get_last_error()) + } + return s, ERROR_NONE +} + +@private +_fstat :: proc(fd: Handle) -> (OS_Stat, Errno) { + // deliberately uninitialized + s: OS_Stat = --- + res := _unix_fstat(fd, &s) + if res == -1 { + return s, Errno(get_last_error()) + } + return s, ERROR_NONE +} + +@private +_fdopendir :: proc(fd: Handle) -> (Dir, Errno) { + dirp := _unix_fdopendir(fd) + if dirp == cast(Dir)nil { + return nil, Errno(get_last_error()) + } + return dirp, ERROR_NONE +} + +@private +_closedir :: proc(dirp: Dir) -> Errno { + rc := _unix_closedir(dirp) + if rc != 0 { + return Errno(get_last_error()) + } + return ERROR_NONE +} + +@private +_rewinddir :: proc(dirp: Dir) { + _unix_rewinddir(dirp) +} + +@private +_readdir :: proc(dirp: Dir) -> (entry: Dirent, err: Errno, end_of_stream: bool) { + result: ^Dirent + rc := _unix_readdir_r(dirp, &entry, &result) + + if rc != 0 { + err = Errno(get_last_error()) + return + } + err = ERROR_NONE + + if result == nil { + end_of_stream = true + return + } + + return +} + +@private +_readlink :: proc(path: string) -> (string, Errno) { + path_cstr := strings.clone_to_cstring(path, context.temp_allocator) + + bufsz : uint = MAX_PATH + buf := make([]byte, MAX_PATH) + for { + rc := _unix_readlink(path_cstr, &(buf[0]), bufsz) + if rc == -1 { + delete(buf) + return "", Errno(get_last_error()) + } else if rc == int(bufsz) { + bufsz += MAX_PATH + delete(buf) + buf = make([]byte, bufsz) + } else { + return strings.string_from_ptr(&buf[0], rc), ERROR_NONE + } + } + unreachable() +} + +// XXX OpenBSD +absolute_path_from_handle :: proc(fd: Handle) -> (string, Errno) { + return "", Errno(ENOSYS) +} + +absolute_path_from_relative :: proc(rel: string) -> (path: string, err: Errno) { + rel := rel + if rel == "" { + rel = "." + } + + rel_cstr := strings.clone_to_cstring(rel, context.temp_allocator) + + path_ptr := _unix_realpath(rel_cstr, nil) + if path_ptr == nil { + return "", Errno(get_last_error()) + } + defer _unix_free(path_ptr) + + path_cstr := transmute(cstring)path_ptr + path = strings.clone( string(path_cstr) ) + + return path, ERROR_NONE +} + +access :: proc(path: string, mask: int) -> (bool, Errno) { + cstr := strings.clone_to_cstring(path, context.temp_allocator) + res := _unix_access(cstr, c.int(mask)) + if res == -1 { + return false, Errno(get_last_error()) + } + return true, ERROR_NONE +} + +heap_alloc :: proc(size: int) -> rawptr { + assert(size >= 0) + return _unix_calloc(1, c.size_t(size)) +} + +heap_resize :: proc(ptr: rawptr, new_size: int) -> rawptr { + // NOTE: _unix_realloc doesn't guarantee new memory will be zeroed on + // POSIX platforms. Ensure your caller takes this into account. + return _unix_realloc(ptr, c.size_t(new_size)) +} + +heap_free :: proc(ptr: rawptr) { + _unix_free(ptr) +} + +getenv :: proc(name: string) -> (string, bool) { + path_str := strings.clone_to_cstring(name, context.temp_allocator) + cstr := _unix_getenv(path_str) + if cstr == nil { + return "", false + } + return string(cstr), true +} + +get_current_directory :: proc() -> string { + buf := make([dynamic]u8, MAX_PATH) + for { + cwd := _unix_getcwd(cstring(raw_data(buf)), c.size_t(len(buf))) + if cwd != nil { + return string(cwd) + } + if Errno(get_last_error()) != ERANGE { + return "" + } + resize(&buf, len(buf) + MAX_PATH) + } + unreachable() +} + +set_current_directory :: proc(path: string) -> (err: Errno) { + cstr := strings.clone_to_cstring(path, context.temp_allocator) + res := _unix_chdir(cstr) + if res == -1 { + return Errno(get_last_error()) + } + return ERROR_NONE +} + +exit :: proc "contextless" (code: int) -> ! { + _unix_exit(c.int(code)) +} + +current_thread_id :: proc "contextless" () -> int { + return _unix_getthrid() +} + +dlopen :: proc(filename: string, flags: int) -> rawptr { + cstr := strings.clone_to_cstring(filename, context.temp_allocator) + handle := _unix_dlopen(cstr, c.int(flags)) + return handle +} +dlsym :: proc(handle: rawptr, symbol: string) -> rawptr { + assert(handle != nil) + cstr := strings.clone_to_cstring(symbol, context.temp_allocator) + proc_handle := _unix_dlsym(handle, cstr) + return proc_handle +} +dlclose :: proc(handle: rawptr) -> bool { + assert(handle != nil) + return _unix_dlclose(handle) == 0 +} +dlerror :: proc() -> string { + return string(_unix_dlerror()) +} + +get_page_size :: proc() -> int { + // NOTE(tetra): The page size never changes, so why do anything complicated + // if we don't have to. + @static page_size := -1 + if page_size != -1 { + return page_size + } + + page_size = int(_unix_getpagesize()) + return page_size +} + + +_alloc_command_line_arguments :: proc() -> []string { + res := make([]string, len(runtime.args__)) + for arg, i in runtime.args__ { + res[i] = string(arg) + } + return res +} diff --git a/core/os/stat_unix.odin b/core/os/stat_unix.odin index 08c6f53c4..2aa9fc283 100644 --- a/core/os/stat_unix.odin +++ b/core/os/stat_unix.odin @@ -1,4 +1,4 @@ -//+build linux, darwin, freebsd +//+build linux, darwin, freebsd, openbsd package os import "core:time" diff --git a/core/path/filepath/path_unix.odin b/core/path/filepath/path_unix.odin index 3e49c4710..d0eaa3635 100644 --- a/core/path/filepath/path_unix.odin +++ b/core/path/filepath/path_unix.odin @@ -1,4 +1,4 @@ -//+build linux, darwin, freebsd +//+build linux, darwin, freebsd, openbsd package filepath when ODIN_OS == .Darwin { @@ -59,6 +59,11 @@ when ODIN_OS == .Darwin { foreign libc { @(link_name="__error") __error :: proc() -> ^i32 --- } +} else when ODIN_OS == .OpenBSD { + @(private) + foreign libc { + @(link_name="__errno") __error :: proc() -> ^i32 --- + } } else { @(private) foreign libc { diff --git a/core/runtime/entry_unix.odin b/core/runtime/entry_unix.odin index dd1e06625..1a3def200 100644 --- a/core/runtime/entry_unix.odin +++ b/core/runtime/entry_unix.odin @@ -1,5 +1,5 @@ //+private -//+build linux, darwin, freebsd +//+build linux, darwin, freebsd, openbsd package runtime import "core:intrinsics" diff --git a/core/sync/channel_unix.odin b/core/sync/channel_unix.odin index d6bac2d71..47aa46004 100644 --- a/core/sync/channel_unix.odin +++ b/core/sync/channel_unix.odin @@ -1,4 +1,4 @@ -// +build linux, darwin, freebsd +// +build linux, darwin, freebsd, openbsd package sync import "core:time" diff --git a/core/sync/sync2/futex_openbsd.odin b/core/sync/sync2/futex_openbsd.odin new file mode 100644 index 000000000..dbc80747b --- /dev/null +++ b/core/sync/sync2/futex_openbsd.odin @@ -0,0 +1,78 @@ +//+private +//+build openbsd +package sync2 + +import "core:c" +import "core:os" +import "core:time" + +FUTEX_WAIT :: 1 +FUTEX_WAKE :: 2 + +FUTEX_PRIVATE_FLAG :: 128 + +FUTEX_WAIT_PRIVATE :: (FUTEX_WAIT | FUTEX_PRIVATE_FLAG) +FUTEX_WAKE_PRIVATE :: (FUTEX_WAKE | FUTEX_PRIVATE_FLAG) + +foreign import libc "system:c" + +foreign libc { + @(link_name="futex") + _unix_futex :: proc "c" (f: ^Futex, op: c.int, val: u32, timeout: rawptr) -> c.int --- +} + +_futex_wait :: proc(f: ^Futex, expected: u32) -> bool { + res := _unix_futex(f, FUTEX_WAIT_PRIVATE, expected, nil) + + if res != -1 { + return true + } + + if os.Errno(os.get_last_error()) == os.ETIMEDOUT { + return false + } + + panic("futex_wait failure") +} + +_futex_wait_with_timeout :: proc(f: ^Futex, expected: u32, duration: time.Duration) -> bool { + if duration <= 0 { + return false + } + + timespec_t :: struct { + tv_sec: c.long, + tv_nsec: c.long, + } + + res := _unix_futex(f, FUTEX_WAIT_PRIVATE, expected, ×pec_t{ + tv_sec = (c.long)(duration/1e9), + tv_nsec = (c.long)(duration%1e9), + }) + + if res != -1 { + return true + } + + if os.Errno(os.get_last_error()) == os.ETIMEDOUT { + return false + } + + panic("futex_wait_with_timeout failure") +} + +_futex_signal :: proc(f: ^Futex) { + res := _unix_futex(f, FUTEX_WAKE_PRIVATE, 1, nil) + + if res == -1 { + panic("futex_wake_single failure") + } +} + +_futex_broadcast :: proc(f: ^Futex) { + res := _unix_futex(f, FUTEX_WAKE_PRIVATE, u32(max(i32)), nil) + + if res == -1 { + panic("_futex_wake_all failure") + } +} diff --git a/core/sync/sync2/primitives_openbsd.odin b/core/sync/sync2/primitives_openbsd.odin new file mode 100644 index 000000000..ef122b02e --- /dev/null +++ b/core/sync/sync2/primitives_openbsd.odin @@ -0,0 +1,9 @@ +//+build openbsd +//+private +package sync2 + +import "core:os" + +_current_thread_id :: proc "contextless" () -> int { + return os.current_thread_id() +} diff --git a/core/sync/sync2/primitives_pthreads.odin b/core/sync/sync2/primitives_pthreads.odin index 8d2c3986d..28053f9cc 100644 --- a/core/sync/sync2/primitives_pthreads.odin +++ b/core/sync/sync2/primitives_pthreads.odin @@ -1,4 +1,4 @@ -//+build linux, freebsd +//+build linux, freebsd, openbsd //+private package sync2 diff --git a/core/sync/sync_openbsd.odin b/core/sync/sync_openbsd.odin new file mode 100644 index 000000000..926655f5b --- /dev/null +++ b/core/sync/sync_openbsd.odin @@ -0,0 +1,36 @@ +package sync + +import "core:sys/unix" +import "core:os" + +current_thread_id :: proc "contextless" () -> int { + return os.current_thread_id() +} + +// The Darwin docs say it best: +// A semaphore is much like a lock, except that a finite number of threads can hold it simultaneously. +// Semaphores can be thought of as being much like piles of tokens; multiple threads can take these tokens, +// but when there are none left, a thread must wait until another thread returns one. +Semaphore :: struct #align 16 { + handle: unix.sem_t, +} + +semaphore_init :: proc(s: ^Semaphore, initial_count := 0) { + assert(unix.sem_init(&s.handle, 0, u32(initial_count)) == 0) +} + +semaphore_destroy :: proc(s: ^Semaphore) { + assert(unix.sem_destroy(&s.handle) == 0) + s.handle = {} +} + +semaphore_post :: proc(s: ^Semaphore, count := 1) { + // NOTE: SPEED: If there's one syscall to do this, we should use it instead of the loop. + for in 0.. ^sem_t --- + + sem_init :: proc(sem: ^sem_t, pshared: c.int, initial_value: c.uint) -> c.int --- + sem_destroy :: proc(sem: ^sem_t) -> c.int --- + sem_post :: proc(sem: ^sem_t) -> c.int --- + sem_wait :: proc(sem: ^sem_t) -> c.int --- + sem_trywait :: proc(sem: ^sem_t) -> c.int --- + //sem_timedwait :: proc(sem: ^sem_t, timeout: time.TimeSpec) -> c.int --- + + // NOTE: unclear whether pthread_yield is well-supported on Linux systems, + // see https://linux.die.net/man/3/pthread_yield + pthread_yield :: proc() --- +} diff --git a/core/sys/unix/pthread_unix.odin b/core/sys/unix/pthread_unix.odin index ccd8f7844..62e3701ab 100644 --- a/core/sys/unix/pthread_unix.odin +++ b/core/sys/unix/pthread_unix.odin @@ -1,4 +1,4 @@ -//+build linux, darwin, freebsd +//+build linux, darwin, freebsd, openbsd package unix foreign import "system:pthread" diff --git a/core/thread/thread_unix.odin b/core/thread/thread_unix.odin index 6cb91df86..b6679bbc2 100644 --- a/core/thread/thread_unix.odin +++ b/core/thread/thread_unix.odin @@ -1,4 +1,4 @@ -// +build linux, darwin, freebsd +// +build linux, darwin, freebsd, openbsd // +private package thread diff --git a/core/time/time_unix.odin b/core/time/time_unix.odin index 9c5c5cc35..37fc1fd3e 100644 --- a/core/time/time_unix.odin +++ b/core/time/time_unix.odin @@ -1,4 +1,4 @@ -//+build linux, darwin, freebsd +//+build linux, darwin, freebsd, openbsd package time IS_SUPPORTED :: true // NOTE: Times on Darwin are UTC. @@ -22,16 +22,28 @@ TimeSpec :: struct { tv_nsec : i64, /* nanoseconds */ } -CLOCK_REALTIME :: 0 // NOTE(tetra): May jump in time, when user changes the system time. -CLOCK_MONOTONIC :: 1 // NOTE(tetra): May stand still while system is asleep. -CLOCK_PROCESS_CPUTIME_ID :: 2 -CLOCK_THREAD_CPUTIME_ID :: 3 -CLOCK_MONOTONIC_RAW :: 4 // NOTE(tetra): "RAW" means: Not adjusted by NTP. -CLOCK_REALTIME_COARSE :: 5 // NOTE(tetra): "COARSE" clocks are apparently much faster, but not "fine-grained." -CLOCK_MONOTONIC_COARSE :: 6 -CLOCK_BOOTTIME :: 7 // NOTE(tetra): Same as MONOTONIC, except also including time system was asleep. -CLOCK_REALTIME_ALARM :: 8 -CLOCK_BOOTTIME_ALARM :: 9 +when ODIN_OS == .OpenBSD { + CLOCK_REALTIME :: 0 + CLOCK_PROCESS_CPUTIME_ID :: 2 + CLOCK_MONOTONIC :: 3 + CLOCK_THREAD_CPUTIME_ID :: 4 + CLOCK_UPTIME :: 5 + CLOCK_BOOTTIME :: 6 + + // CLOCK_MONOTONIC_RAW doesn't exist, use CLOCK_MONOTONIC + CLOCK_MONOTONIC_RAW :: CLOCK_MONOTONIC +} else { + CLOCK_REALTIME :: 0 // NOTE(tetra): May jump in time, when user changes the system time. + CLOCK_MONOTONIC :: 1 // NOTE(tetra): May stand still while system is asleep. + CLOCK_PROCESS_CPUTIME_ID :: 2 + CLOCK_THREAD_CPUTIME_ID :: 3 + CLOCK_MONOTONIC_RAW :: 4 // NOTE(tetra): "RAW" means: Not adjusted by NTP. + CLOCK_REALTIME_COARSE :: 5 // NOTE(tetra): "COARSE" clocks are apparently much faster, but not "fine-grained." + CLOCK_MONOTONIC_COARSE :: 6 + CLOCK_BOOTTIME :: 7 // NOTE(tetra): Same as MONOTONIC, except also including time system was asleep. + CLOCK_REALTIME_ALARM :: 8 + CLOCK_BOOTTIME_ALARM :: 9 +} // TODO(tetra, 2019-11-05): The original implementation of this package for Darwin used this constants. // I do not know if Darwin programmers are used to the existance of these constants or not, so diff --git a/src/bug_report.cpp b/src/bug_report.cpp index 4dd251f24..7f6b668e8 100644 --- a/src/bug_report.cpp +++ b/src/bug_report.cpp @@ -17,6 +17,10 @@ #include #endif +#if defined(GB_SYSTEM_OPENBSD) + #include +#endif + /* NOTE(Jeroen): This prints the Windows product edition only, to be called from `print_platform_details`. */ @@ -643,6 +647,14 @@ void print_bug_report_help() { } else { gb_printf("macOS: Unknown\n"); } + #elif defined(GB_SYSTEM_OPENBSD) + struct utsname un; + + if (uname(&un) != -1) { + gb_printf("%s %s %s %s\n", un.sysname, un.release, un.version, un.machine); + } else { + gb_printf("OpenBSD: Unknown\n"); + } #else gb_printf("Unknown\n"); @@ -657,4 +669,4 @@ void print_bug_report_help() { And RAM info. */ report_ram_info(); -} \ No newline at end of file +} diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 610e4f847..72a4b35cc 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -16,6 +16,7 @@ enum TargetOsKind { TargetOs_linux, TargetOs_essence, TargetOs_freebsd, + TargetOs_openbsd, TargetOs_wasi, TargetOs_js, @@ -53,6 +54,7 @@ String target_os_names[TargetOs_COUNT] = { str_lit("linux"), str_lit("essence"), str_lit("freebsd"), + str_lit("openbsd"), str_lit("wasi"), str_lit("js"), @@ -354,6 +356,15 @@ gb_global TargetMetrics target_freebsd_amd64 = { str_lit("e-m:w-i64:64-f80:128-n8:16:32:64-S128"), }; +gb_global TargetMetrics target_openbsd_amd64 = { + TargetOs_openbsd, + TargetArch_amd64, + 8, + 16, + str_lit("x86_64-unknown-openbsd-elf"), + str_lit("e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"), +}; + gb_global TargetMetrics target_essence_amd64 = { TargetOs_essence, TargetArch_amd64, @@ -417,6 +428,7 @@ gb_global NamedTargetMetrics named_targets[] = { { str_lit("windows_amd64"), &target_windows_amd64 }, { str_lit("freebsd_386"), &target_freebsd_386 }, { str_lit("freebsd_amd64"), &target_freebsd_amd64 }, + { str_lit("openbsd_amd64"), &target_openbsd_amd64 }, { str_lit("freestanding_wasm32"), &target_freestanding_wasm32 }, { str_lit("wasi_wasm32"), &target_wasi_wasm32 }, { str_lit("js_wasm32"), &target_js_wasm32 }, @@ -723,6 +735,7 @@ String internal_odin_root_dir(void) { #elif defined(GB_SYSTEM_DRAGONFLYBSD) len = readlink("/proc/curproc/file", &path_buf[0], path_buf.count); #else + // XXX OpenBSD len = readlink("/proc/self/exe", &path_buf[0], path_buf.count); #endif if(len == 0) { @@ -922,6 +935,8 @@ void init_build_context(TargetMetrics *cross_target) { #endif #elif defined(GB_SYSTEM_FREEBSD) metrics = &target_freebsd_amd64; + #elif defined(GB_SYSTEM_OPENBSD) + metrics = &target_openbsd_amd64; #elif defined(GB_CPU_ARM) metrics = &target_linux_arm64; #else @@ -980,6 +995,9 @@ void init_build_context(TargetMetrics *cross_target) { case TargetOs_freebsd: bc->link_flags = str_lit("-arch x86-64 "); break; + case TargetOs_openbsd: + bc->link_flags = str_lit("-arch x86-64 "); + break; } } else if (bc->metrics.arch == TargetArch_i386) { switch (bc->metrics.os) { diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index eb9d7f293..69cc40de8 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -3506,6 +3506,7 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 case TargetOs_linux: case TargetOs_essence: case TargetOs_freebsd: + case TargetOs_openbsd: switch (build_context.metrics.arch) { case TargetArch_i386: case TargetArch_amd64: diff --git a/src/checker.cpp b/src/checker.cpp index f440b7c9a..5a7ece263 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -906,6 +906,7 @@ void init_universal(void) { {"Linux", TargetOs_linux}, {"Essence", TargetOs_essence}, {"FreeBSD", TargetOs_freebsd}, + {"OpenBSD", TargetOs_openbsd}, {"WASI", TargetOs_wasi}, {"JS", TargetOs_js}, {"Freestanding", TargetOs_freestanding}, diff --git a/src/common.cpp b/src/common.cpp index d3ee95b76..aaacda04b 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -848,7 +848,7 @@ ReadDirectoryError read_directory(String path, Array *fi) { return ReadDirectory_None; } -#elif defined(GB_SYSTEM_LINUX) || defined(GB_SYSTEM_OSX) || defined(GB_SYSTEM_FREEBSD) +#elif defined(GB_SYSTEM_LINUX) || defined(GB_SYSTEM_OSX) || defined(GB_SYSTEM_FREEBSD) || defined(GB_SYSTEM_OPENBSD) #include diff --git a/src/gb/gb.h b/src/gb/gb.h index a9d6378c9..293e5063a 100644 --- a/src/gb/gb.h +++ b/src/gb/gb.h @@ -79,6 +79,10 @@ extern "C" { #ifndef GB_SYSTEM_FREEBSD #define GB_SYSTEM_FREEBSD 1 #endif + #elif defined(__OpenBSD__) + #ifndef GB_SYSTEM_OPENBSD + #define GB_SYSTEM_OPENBSD 1 + #endif #else #error This UNIX operating system is not supported #endif @@ -199,7 +203,7 @@ extern "C" { #endif #include // NOTE(bill): malloc on linux #include - #if !defined(GB_SYSTEM_OSX) && !defined(__FreeBSD__) + #if !defined(GB_SYSTEM_OSX) && !defined(__FreeBSD__) && !defined(__OpenBSD__) #include #endif #include @@ -235,6 +239,15 @@ extern "C" { #define sendfile(out, in, offset, count) sendfile(out, in, offset, count, NULL, NULL, 0) #endif +#if defined(GB_SYSTEM_OPENBSD) + #include + #include + #define lseek64 lseek + + // XXX OpenBSD + #define sendfile(out, in, offset, count) (-1) +#endif + #if defined(GB_SYSTEM_UNIX) #include #endif @@ -783,6 +796,13 @@ typedef struct gbAffinity { isize thread_count; isize threads_per_core; } gbAffinity; +#elif defined(GB_SYSTEM_OPENBSD) +typedef struct gbAffinity { + b32 is_accurate; + isize core_count; + isize thread_count; + isize threads_per_core; +} gbAffinity; #else #error TODO(bill): Unknown system #endif @@ -3678,6 +3698,30 @@ b32 gb_affinity_set(gbAffinity *a, isize core, isize thread_index) { return true; } +isize gb_affinity_thread_count_for_core(gbAffinity *a, isize core) { + GB_ASSERT(0 <= core && core < a->core_count); + return a->threads_per_core; +} + +#elif defined(GB_SYSTEM_OPENBSD) +#include + +void gb_affinity_init(gbAffinity *a) { + a->core_count = sysconf(_SC_NPROCESSORS_ONLN); + a->threads_per_core = 1; + a->is_accurate = a->core_count > 0; + a->core_count = a->is_accurate ? a->core_count : 1; + a->thread_count = a->core_count; +} + +void gb_affinity_destroy(gbAffinity *a) { + gb_unused(a); +} + +b32 gb_affinity_set(gbAffinity *a, isize core, isize thread_index) { + return true; +} + isize gb_affinity_thread_count_for_core(gbAffinity *a, isize core) { GB_ASSERT(0 <= core && core < a->core_count); return a->threads_per_core; diff --git a/src/threading.cpp b/src/threading.cpp index 50d0dfed1..63e3415b2 100644 --- a/src/threading.cpp +++ b/src/threading.cpp @@ -486,7 +486,7 @@ void thread_set_name(Thread *t, char const *name) { #elif defined(GB_SYSTEM_OSX) // TODO(bill): Test if this works pthread_setname_np(name); -#elif defined(GB_SYSTEM_FREEBSD) +#elif defined(GB_SYSTEM_FREEBSD) || defined(GB_SYSTEM_OPENBSD) pthread_set_name_np(t->posix_handle, name); #else // TODO(bill): Test if this works -- cgit v1.2.3 From 278e239973ab1e680bd36f90c069ec798930e54b Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 28 Feb 2022 13:39:27 +0000 Subject: Commit rest of code for `-disallow-rtti` --- src/build_settings.cpp | 3 ++- src/check_builtin.cpp | 18 +++++++++++++----- src/check_decl.cpp | 2 ++ src/check_expr.cpp | 2 ++ src/check_type.cpp | 2 ++ src/checker.cpp | 25 ++++++++++++++++++++++++- src/llvm_backend.cpp | 6 +++++- src/llvm_backend_expr.cpp | 17 ++++++++++++++--- src/llvm_backend_type.cpp | 2 ++ src/llvm_backend_utility.cpp | 30 ++++++++++++++++++++++-------- src/main.cpp | 7 +++++++ 11 files changed, 95 insertions(+), 19 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/build_settings.cpp b/src/build_settings.cpp index d6cdd7006..b2d6c4f43 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -277,6 +277,8 @@ struct BuildContext { bool copy_file_contents; + bool disallow_rtti; + RelocMode reloc_mode; bool disable_red_zone; @@ -946,7 +948,6 @@ void init_build_context(TargetMetrics *cross_target) { } } - bc->copy_file_contents = true; TargetMetrics *metrics = nullptr; diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index eb9d7f293..5561da01b 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -1241,6 +1241,10 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 if (c->scope->flags&ScopeFlag_Global) { compiler_error("'type_info_of' Cannot be declared within the runtime package due to how the internals of the compiler works"); } + if (build_context.disallow_rtti) { + error(call, "'%.*s' has been disallowed", LIT(builtin_name)); + return false; + } // NOTE(bill): The type information may not be setup yet init_core_type_info(c->checker); @@ -1253,9 +1257,9 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 Type *t = o.type; if (t == nullptr || t == t_invalid || is_type_asm_proc(o.type) || is_type_polymorphic(t)) { if (is_type_polymorphic(t)) { - error(ce->args[0], "Invalid argument for 'type_info_of', unspecialized polymorphic type"); + error(ce->args[0], "Invalid argument for '%.*s', unspecialized polymorphic type", LIT(builtin_name)); } else { - error(ce->args[0], "Invalid argument for 'type_info_of'"); + error(ce->args[0], "Invalid argument for '%.*s'", LIT(builtin_name)); } return false; } @@ -1266,7 +1270,7 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 if (is_operand_value(o) && is_type_typeid(t)) { add_package_dependency(c, "runtime", "__type_info_of"); } else if (o.mode != Addressing_Type) { - error(expr, "Expected a type or typeid for 'type_info_of'"); + error(expr, "Expected a type or typeid for '%.*s'", LIT(builtin_name)); return false; } @@ -1280,6 +1284,10 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 if (c->scope->flags&ScopeFlag_Global) { compiler_error("'typeid_of' Cannot be declared within the runtime package due to how the internals of the compiler works"); } + if (build_context.disallow_rtti) { + error(call, "'%.*s' has been disallowed", LIT(builtin_name)); + return false; + } // NOTE(bill): The type information may not be setup yet init_core_type_info(c->checker); @@ -1291,7 +1299,7 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 } Type *t = o.type; if (t == nullptr || t == t_invalid || is_type_asm_proc(o.type) || is_type_polymorphic(operand->type)) { - error(ce->args[0], "Invalid argument for 'typeid_of'"); + error(ce->args[0], "Invalid argument for '%.*s'", LIT(builtin_name)); return false; } t = default_type(t); @@ -1299,7 +1307,7 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 add_type_info_type(c, t); if (o.mode != Addressing_Type) { - error(expr, "Expected a type for 'typeid_of'"); + error(expr, "Expected a type for '%.*s'", LIT(builtin_name)); return false; } diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 3fdd944f9..b3b1e4474 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -1205,6 +1205,8 @@ void check_global_variable_decl(CheckerContext *ctx, Entity *&e, Ast *type_expr, Operand o = {}; check_expr_with_type_hint(ctx, &o, init_expr, e->type); check_init_variable(ctx, e, &o, str_lit("variable declaration")); + + 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) { diff --git a/src/check_expr.cpp b/src/check_expr.cpp index e07dc3d60..f1bcb4cd9 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -9352,6 +9352,8 @@ ExprKind check_expr_base(CheckerContext *c, Operand *o, Ast *node, Type *type_hi if (o->type != nullptr && is_type_untyped(o->type)) { add_untyped(c, node, o->mode, o->type, o->value); } + check_rtti_type_disallowed(node, o->type, "An expression is using a type, %s, which has been disallowed"); + add_type_and_value(c->info, node, o->mode, o->type, o->value); return kind; } diff --git a/src/check_type.cpp b/src/check_type.cpp index c2324ee5a..ff2c3d6a6 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -3031,5 +3031,7 @@ Type *check_type_expr(CheckerContext *ctx, Ast *e, Type *named_type) { } set_base_type(named_type, type); + check_rtti_type_disallowed(e, type, "Use of a type, %s, which has been disallowed"); + return type; } diff --git a/src/checker.cpp b/src/checker.cpp index fe1d362fa..e6445d752 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -29,6 +29,23 @@ bool is_operand_undef(Operand o) { return o.mode == Addressing_Value && o.type == t_untyped_undef; } +bool check_rtti_type_disallowed(Token const &token, Type *type, char const *format) { + if (build_context.disallow_rtti && type) { + if (is_type_any(type)) { + gbString t = type_to_string(type); + error(token, format, t); + gb_string_free(t); + return true; + } + } + return false; +} + +bool check_rtti_type_disallowed(Ast *expr, Type *type, char const *format) { + GB_ASSERT(expr != nullptr); + return check_rtti_type_disallowed(ast_token(expr), type, format); +} + void scope_reset(Scope *scope) { if (scope == nullptr) return; @@ -875,7 +892,8 @@ void init_universal(void) { // Types for (isize i = 0; i < gb_count_of(basic_types); i++) { - add_global_type_entity(basic_types[i].Basic.name, &basic_types[i]); + String const &name = basic_types[i].Basic.name; + add_global_type_entity(name, &basic_types[i]); } add_global_type_entity(str_lit("byte"), &basic_types[Basic_u8]); @@ -977,6 +995,7 @@ void init_universal(void) { add_global_bool_constant("ODIN_TEST", bc->command_kind == Command_test); add_global_bool_constant("ODIN_NO_ENTRY_POINT", bc->no_entry_point); add_global_bool_constant("ODIN_FOREIGN_ERROR_PROCEDURES", bc->ODIN_FOREIGN_ERROR_PROCEDURES); + add_global_bool_constant("ODIN_DISALLOW_RTTI", bc->disallow_rtti); // Builtin Procedures @@ -1669,6 +1688,10 @@ void add_implicit_entity(CheckerContext *c, Ast *clause, Entity *e) { void add_type_info_type(CheckerContext *c, Type *t) { void add_type_info_type_internal(CheckerContext *c, Type *t); + if (build_context.disallow_rtti) { + return; + } + mutex_lock(&c->info->type_info_mutex); add_type_info_type_internal(c, t); mutex_unlock(&c->info->type_info_mutex); diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 6ca256c4b..04c3200f8 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -1285,7 +1285,11 @@ void lb_generate_code(lbGenerator *gen) { // x86-64-v3: (close to Haswell) AVX, AVX2, BMI1, BMI2, F16C, FMA, LZCNT, MOVBE, XSAVE // x86-64-v4: AVX512F, AVX512BW, AVX512CD, AVX512DQ, AVX512VL if (ODIN_LLVM_MINIMUM_VERSION_12) { - llvm_cpu = "x86-64-v2"; + if (build_context.metrics.os == TargetOs_freestanding) { + llvm_cpu = "x86-64"; + } else { + llvm_cpu = "x86-64-v2"; + } } } diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp index 844deb43c..18b66572d 100644 --- a/src/llvm_backend_expr.cpp +++ b/src/llvm_backend_expr.cpp @@ -2809,16 +2809,25 @@ lbValue lb_build_unary_and(lbProcedure *p, Ast *expr) { src_tag = lb_emit_load(p, lb_emit_union_tag_ptr(p, v)); dst_tag = lb_const_union_tag(p->module, src_type, dst_type); } + + + isize arg_count = 6; + if (build_context.disallow_rtti) { + arg_count = 4; + } + lbValue ok = lb_emit_comp(p, Token_CmpEq, src_tag, dst_tag); - auto args = array_make(permanent_allocator(), 6); + auto args = array_make(permanent_allocator(), arg_count); args[0] = ok; args[1] = lb_find_or_add_entity_string(p->module, get_file_path_string(pos.file_id)); args[2] = lb_const_int(p->module, t_i32, pos.line); args[3] = lb_const_int(p->module, t_i32, pos.column); - args[4] = lb_typeid(p->module, src_type); - args[5] = lb_typeid(p->module, dst_type); + if (!build_context.disallow_rtti) { + args[4] = lb_typeid(p->module, src_type); + args[5] = lb_typeid(p->module, dst_type); + } lb_emit_runtime_call(p, "type_assertion_check", args); } @@ -2831,6 +2840,8 @@ lbValue lb_build_unary_and(lbProcedure *p, Ast *expr) { } lbValue data_ptr = lb_emit_struct_ev(p, v, 0); if ((p->state_flags & StateFlag_no_type_assert) == 0) { + GB_ASSERT(!build_context.disallow_rtti); + lbValue any_id = lb_emit_struct_ev(p, v, 1); lbValue id = lb_typeid(p->module, type); diff --git a/src/llvm_backend_type.cpp b/src/llvm_backend_type.cpp index 1d6297164..1aac75f9c 100644 --- a/src/llvm_backend_type.cpp +++ b/src/llvm_backend_type.cpp @@ -14,6 +14,8 @@ isize lb_type_info_index(CheckerInfo *info, Type *type, bool err_on_not_found=tr } lbValue lb_typeid(lbModule *m, Type *type) { + GB_ASSERT(!build_context.disallow_rtti); + type = default_type(type); u64 id = cast(u64)lb_type_info_index(m->info, type); diff --git a/src/llvm_backend_utility.cpp b/src/llvm_backend_utility.cpp index 98b7e07f0..fb52a9bd6 100644 --- a/src/llvm_backend_utility.cpp +++ b/src/llvm_backend_utility.cpp @@ -676,17 +676,24 @@ lbValue lb_emit_union_cast(lbProcedure *p, lbValue value, Type *type, TokenPos p // NOTE(bill): Panic on invalid conversion Type *dst_type = tuple->Tuple.variables[0]->type; + isize arg_count = 7; + if (build_context.disallow_rtti) { + arg_count = 4; + } + lbValue ok = lb_emit_load(p, lb_emit_struct_ep(p, v.addr, 1)); - auto args = array_make(permanent_allocator(), 7); + auto args = array_make(permanent_allocator(), arg_count); args[0] = ok; args[1] = lb_const_string(m, get_file_path_string(pos.file_id)); args[2] = lb_const_int(m, t_i32, pos.line); args[3] = lb_const_int(m, t_i32, pos.column); - args[4] = lb_typeid(m, src_type); - args[5] = lb_typeid(m, dst_type); - args[6] = lb_emit_conv(p, value_, t_rawptr); + if (!build_context.disallow_rtti) { + args[4] = lb_typeid(m, src_type); + args[5] = lb_typeid(m, dst_type); + args[6] = lb_emit_conv(p, value_, t_rawptr); + } lb_emit_runtime_call(p, "type_assertion_check2", args); return lb_emit_load(p, lb_emit_struct_ep(p, v.addr, 0)); @@ -744,16 +751,23 @@ lbAddr lb_emit_any_cast_addr(lbProcedure *p, lbValue value, Type *type, TokenPos if (!is_tuple) { // NOTE(bill): Panic on invalid conversion lbValue ok = lb_emit_load(p, lb_emit_struct_ep(p, v.addr, 1)); - auto args = array_make(permanent_allocator(), 7); + + isize arg_count = 7; + if (build_context.disallow_rtti) { + arg_count = 4; + } + auto args = array_make(permanent_allocator(), arg_count); args[0] = ok; args[1] = lb_const_string(m, get_file_path_string(pos.file_id)); args[2] = lb_const_int(m, t_i32, pos.line); args[3] = lb_const_int(m, t_i32, pos.column); - args[4] = any_typeid; - args[5] = dst_typeid; - args[6] = lb_emit_struct_ev(p, value, 0);; + if (!build_context.disallow_rtti) { + args[4] = any_typeid; + args[5] = dst_typeid; + args[6] = lb_emit_struct_ev(p, value, 0); + } lb_emit_runtime_call(p, "type_assertion_check2", args); return lb_addr(lb_emit_struct_ep(p, v.addr, 0)); diff --git a/src/main.cpp b/src/main.cpp index 8f4155d39..d2263f5a7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -638,6 +638,7 @@ enum BuildFlagKind { BuildFlag_StrictStyle, BuildFlag_StrictStyleInitOnly, BuildFlag_ForeignErrorProcedures, + BuildFlag_DisallowRTTI, BuildFlag_Compact, BuildFlag_GlobalDefinitions, @@ -796,6 +797,9 @@ bool parse_build_flags(Array args) { add_flag(&build_flags, BuildFlag_StrictStyleInitOnly, str_lit("strict-style-init-only"), BuildFlagParam_None, Command__does_check); add_flag(&build_flags, BuildFlag_ForeignErrorProcedures, str_lit("foreign-error-procedures"), BuildFlagParam_None, Command__does_check); + add_flag(&build_flags, BuildFlag_DisallowRTTI, str_lit("disallow-rtti"), 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); @@ -1390,6 +1394,9 @@ bool parse_build_flags(Array args) { case BuildFlag_DisallowDo: build_context.disallow_do = true; break; + case BuildFlag_DisallowRTTI: + build_context.disallow_rtti = true; + break; case BuildFlag_DefaultToNilAllocator: build_context.ODIN_DEFAULT_TO_NIL_ALLOCATOR = true; break; -- cgit v1.2.3 From 4f3b5d8dcb3be98d7b11efd49f3aec758e51bd2a Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 28 Feb 2022 15:29:08 +0000 Subject: Clean up `generate_minimum_dependency_set` code --- src/checker.cpp | 75 +++++++++++++++++++++++++++++++-------------------------- 1 file changed, 41 insertions(+), 34 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index e6445d752..660691276 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -2204,21 +2204,25 @@ void generate_minimum_dependency_set(Checker *c, Entity *start) { ptr_set_init(&c->info.minimum_dependency_set, heap_allocator(), min_dep_set_cap); ptr_set_init(&c->info.minimum_dependency_type_info_set, heap_allocator()); - String required_runtime_entities[] = { +#define FORCE_ADD_RUNTIME_ENTITIES(condition, ...) do { \ + if (condition) { \ + String entities[] = {__VA_ARGS__}; \ + for (isize i = 0; i < gb_count_of(entities); i++) { \ + force_add_dependency_entity(c, c->info.runtime_package->scope, entities[i]); \ + } \ + } \ +} while (0) + + // required runtime entities + FORCE_ADD_RUNTIME_ENTITIES(true, // Odin types - str_lit("Type_Info"), str_lit("Source_Code_Location"), str_lit("Context"), str_lit("Allocator"), str_lit("Logger"), - // Global variables - str_lit("args__"), - str_lit("type_table"), - // Odin internal procedures str_lit("__init_context"), - str_lit("__type_info_of"), str_lit("cstring_to_string"), str_lit("_cleanup_runtime"), @@ -2251,35 +2255,36 @@ void generate_minimum_dependency_set(Checker *c, Entity *start) { // WASM Specific str_lit("__ashlti3"), str_lit("__multi3"), - }; - for (isize i = 0; i < gb_count_of(required_runtime_entities); i++) { - force_add_dependency_entity(c, c->info.runtime_package->scope, required_runtime_entities[i]); - } + ); - if (build_context.no_crt) { - String required_no_crt_entities[] = { - // NOTE(bill): Only if these exist - str_lit("_tls_index"), - str_lit("_fltused"), - }; - for (isize i = 0; i < gb_count_of(required_no_crt_entities); i++) { - force_add_dependency_entity(c, c->info.runtime_package->scope, required_no_crt_entities[i]); - } - } + FORCE_ADD_RUNTIME_ENTITIES(!build_context.disallow_rtti, + // Odin types + str_lit("Type_Info"), - if (!build_context.no_bounds_check) { - String bounds_check_entities[] = { - // Bounds checking related procedures - str_lit("bounds_check_error"), - str_lit("matrix_bounds_check_error"), - str_lit("slice_expr_error_hi"), - str_lit("slice_expr_error_lo_hi"), - str_lit("multi_pointer_slice_expr_error"), - }; - for (isize i = 0; i < gb_count_of(bounds_check_entities); i++) { - force_add_dependency_entity(c, c->info.runtime_package->scope, bounds_check_entities[i]); - } - } + // Global variables + str_lit("type_table"), + str_lit("__type_info_of"), + ); + + FORCE_ADD_RUNTIME_ENTITIES(!build_context.no_entry_point, + // Global variables + str_lit("args__"), + ); + + FORCE_ADD_RUNTIME_ENTITIES(build_context.no_crt, + // NOTE(bill): Only if these exist + str_lit("_tls_index"), + str_lit("_fltused"), + ); + + FORCE_ADD_RUNTIME_ENTITIES(!build_context.no_bounds_check, + // Bounds checking related procedures + str_lit("bounds_check_error"), + str_lit("matrix_bounds_check_error"), + str_lit("slice_expr_error_hi"), + str_lit("slice_expr_error_lo_hi"), + str_lit("multi_pointer_slice_expr_error"), + ); for_array(i, c->info.definitions) { Entity *e = c->info.definitions[i]; @@ -2401,6 +2406,8 @@ void generate_minimum_dependency_set(Checker *c, Entity *start) { start->flags |= EntityFlag_Used; add_dependency_to_set(c, start); } + +#undef FORCE_ADD_RUNTIME_ENTITIES } bool is_entity_a_dependency(Entity *e) { -- cgit v1.2.3 From 410b85b5c7f768543e03c9fc6f47f8c2efcd602b Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 28 Feb 2022 15:40:00 +0000 Subject: Disallow `@(thread_local)` on wasm targets --- src/check_decl.cpp | 4 ++++ src/check_stmt.cpp | 5 ++++- src/checker.cpp | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/check_decl.cpp b/src/check_decl.cpp index b3b1e4474..12b0e43cb 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -1130,6 +1130,10 @@ void check_global_variable_decl(CheckerContext *ctx, Entity *&e, Ast *type_expr, } ac.link_name = handle_link_name(ctx, e->token, ac.link_name, ac.link_prefix); + if (is_arch_wasm() && e->Variable.thread_local_model.len != 0) { + error(e->token, "@(thread_local) is not supported for this target platform"); + } + String context_name = str_lit("variable declaration"); if (type_expr != nullptr) { diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index 7cae1893f..f2c830c1b 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -2152,7 +2152,6 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) { e->state = EntityState_Resolved; } ac.link_name = handle_link_name(ctx, e->token, ac.link_name, ac.link_prefix); - e->Variable.thread_local_model = ac.thread_local_model; if (ac.link_name.len > 0) { e->Variable.link_name = ac.link_name; @@ -2182,6 +2181,10 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) { } e->Variable.thread_local_model = ac.thread_local_model; } + + if (is_arch_wasm() && e->Variable.thread_local_model.len != 0) { + error(e->token, "@(thread_local) is not supported for this target platform"); + } if (ac.is_static && ac.thread_local_model != "") { diff --git a/src/checker.cpp b/src/checker.cpp index 660691276..b1abdcb8a 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -2271,7 +2271,7 @@ void generate_minimum_dependency_set(Checker *c, Entity *start) { str_lit("args__"), ); - FORCE_ADD_RUNTIME_ENTITIES(build_context.no_crt, + FORCE_ADD_RUNTIME_ENTITIES((build_context.no_crt && !is_arch_wasm()), // NOTE(bill): Only if these exist str_lit("_tls_index"), str_lit("_fltused"), -- cgit v1.2.3 From a68f0b2d72a3883879da124321868afcdac3b9d6 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 18 Mar 2022 22:18:12 +0000 Subject: Improve procedure group selection based on the minimum number of arguments --- src/check_expr.cpp | 79 +++++++++++++++++++++++++++++++++++++++++++----------- src/check_type.cpp | 14 ---------- src/checker.cpp | 9 +++++++ src/entity.cpp | 10 +++++++ src/types.cpp | 1 - 5 files changed, 82 insertions(+), 31 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 577f3b07c..b7039fd9a 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -4872,25 +4872,16 @@ bool is_expr_constant_zero(Ast *expr) { return false; } - -CALL_ARGUMENT_CHECKER(check_call_arguments_internal) { - ast_node(ce, CallExpr, call); - GB_ASSERT(is_type_proc(proc_type)); - proc_type = base_type(proc_type); - TypeProc *pt = &proc_type->Proc; - +isize get_procedure_param_count_excluding_defaults(Type *pt, isize *param_count_) { + GB_ASSERT(pt != nullptr); + GB_ASSERT(pt->kind == Type_Proc); isize param_count = 0; isize param_count_excluding_defaults = 0; - bool variadic = pt->variadic; - bool vari_expand = (ce->ellipsis.pos.line != 0); - i64 score = 0; - bool show_error = show_error_mode == CallArgumentMode_ShowErrors; - - + bool variadic = pt->Proc.variadic; TypeTuple *param_tuple = nullptr; - if (pt->params != nullptr) { - param_tuple = &pt->params->Tuple; + if (pt->Proc.params != nullptr) { + param_tuple = &pt->Proc.params->Tuple; param_count = param_tuple->variables.count; if (variadic) { @@ -4930,6 +4921,31 @@ CALL_ARGUMENT_CHECKER(check_call_arguments_internal) { } } + if (param_count_) *param_count_ = param_count; + return param_count_excluding_defaults; +} + + +CALL_ARGUMENT_CHECKER(check_call_arguments_internal) { + ast_node(ce, CallExpr, call); + GB_ASSERT(is_type_proc(proc_type)); + proc_type = base_type(proc_type); + TypeProc *pt = &proc_type->Proc; + + isize param_count = 0; + isize param_count_excluding_defaults = get_procedure_param_count_excluding_defaults(proc_type, ¶m_count); + bool variadic = pt->variadic; + bool vari_expand = (ce->ellipsis.pos.line != 0); + i64 score = 0; + bool show_error = show_error_mode == CallArgumentMode_ShowErrors; + + + TypeTuple *param_tuple = nullptr; + if (pt->params != nullptr) { + param_tuple = &pt->params->Tuple; + } + + CallArgumentError err = CallArgumentError_None; Type *final_proc_type = proc_type; Entity *gen_entity = nullptr; @@ -5602,7 +5618,37 @@ CallArgumentData check_call_arguments(CheckerContext *c, Operand *operand, Type if (operand->mode == Addressing_ProcGroup) { check_entity_decl(c, operand->proc_group, nullptr, nullptr); - Array procs = proc_group_entities(c, *operand); + auto procs = proc_group_entities_cloned(c, *operand); + + if (procs.count > 1) { + isize max_arg_count = args.count; + for_array(i, args) { + // NOTE(bill): The only thing that may have multiple values + // will be a call expression (assuming `or_return` and `()` will be stripped) + Ast *arg = strip_or_return_expr(args[i]); + if (arg && arg->kind == Ast_CallExpr) { + max_arg_count = ISIZE_MAX; + break; + } + } + + for (isize proc_index = 0; proc_index < procs.count; /**/) { + Entity *proc = procs[proc_index]; + Type *pt = base_type(proc->type); + if (!(pt != nullptr && is_type_proc(pt))) { + continue; + } + + isize param_count = 0; + isize param_count_excluding_defaults = get_procedure_param_count_excluding_defaults(pt, ¶m_count); + + if (param_count_excluding_defaults > max_arg_count) { + array_unordered_remove(&procs, proc_index); + } else { + proc_index++; + } + } + } if (procs.count == 1) { Ast *ident = operand->expr; @@ -5632,6 +5678,7 @@ CallArgumentData check_call_arguments(CheckerContext *c, Operand *operand, Type return data; } + Entity **lhs = nullptr; isize lhs_count = -1; diff --git a/src/check_type.cpp b/src/check_type.cpp index ecb2c26ea..3c7f33a46 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -1960,20 +1960,6 @@ bool check_procedure_type(CheckerContext *ctx, Type *type, Ast *proc_type_node, if (params) param_count = params ->Tuple.variables.count; if (results) result_count = results->Tuple.variables.count; - if (param_count > 0) { - for_array(i, params->Tuple.variables) { - Entity *param = params->Tuple.variables[i]; - if (param->kind == Entity_Variable) { - ParameterValue pv = param->Variable.param_value; - if (pv.kind == ParameterValue_Constant && - pv.value.kind == ExactValue_Procedure) { - type->Proc.has_proc_default_values = true; - break; - } - } - } - } - if (result_count > 0) { Entity *first = results->Tuple.variables[0]; type->Proc.has_named_results = first->token.string != ""; diff --git a/src/checker.cpp b/src/checker.cpp index ea300afd9..53bba654d 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -2657,6 +2657,15 @@ Array proc_group_entities(CheckerContext *c, Operand o) { return procs; } +Array proc_group_entities_cloned(CheckerContext *c, Operand o) { + auto entities = proc_group_entities(c, o); + if (entities.count == 0) { + return {}; + } + return array_clone(permanent_allocator(), entities); +} + + void init_core_type_info(Checker *c) { diff --git a/src/entity.cpp b/src/entity.cpp index f5720293f..17fa884e1 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -115,6 +115,16 @@ struct ParameterValue { }; }; +bool has_parameter_value(ParameterValue const ¶m_value) { + if (param_value.kind != ParameterValue_Invalid) { + return true; + } + if (param_value.original_ast_expr != nullptr) { + return true; + } + return false; +} + enum EntityConstantFlags : u32 { EntityConstantFlag_ImplicitEnumValue = 1<<0, }; diff --git a/src/types.cpp b/src/types.cpp index 58ccdf5b9..ef770c846 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -186,7 +186,6 @@ struct TypeProc { bool c_vararg; bool is_polymorphic; bool is_poly_specialized; - bool has_proc_default_values; bool has_named_results; bool diverging; // no return bool return_by_pointer; -- cgit v1.2.3 From 203382461b43db30977c17f51929a565c1f3a229 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 31 Mar 2022 00:14:49 +0100 Subject: Replace the atomic intrinsics Matching C11 in style --- src/check_builtin.cpp | 191 +++++++++++++++++++++++++++++------------- src/checker.cpp | 25 +++++- src/checker_builtin_procs.hpp | 175 +++++++++----------------------------- src/llvm_backend_proc.cpp | 170 ++++++++++--------------------------- src/llvm_backend_utility.cpp | 22 +++++ src/types.cpp | 13 +++ 6 files changed, 272 insertions(+), 324 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index e480704e3..3fe0f1048 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -379,6 +379,32 @@ 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, char const *extra_message = nullptr) { + Operand x = {}; + check_expr_with_type_hint(c, &x, expr, t_atomic_memory_order); + if (x.mode == Addressing_Invalid) { + return false; + } + if (!are_types_identical(x.type, t_atomic_memory_order) || x.mode != Addressing_Constant) { + gbString str = type_to_string(x.type); + if (extra_message) { + error(x.expr, "Expected a constant Atomic_Memory_Order value for the %s of '%.*s', got %s", extra_message, LIT(builtin_name), str); + } else { + error(x.expr, "Expected a constant Atomic_Memory_Order value for '%.*s', got %s", LIT(builtin_name), str); + } + gb_string_free(str); + return false; + } + i64 value = exact_value_to_i64(x.value); + if (value < 0 || value >= OdinAtomicMemoryOrder_COUNT) { + error(x.expr, "Illegal Atomic_Memory_Order value, got %lld", cast(long long)value); + return false; + } + + return true; + +} + 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) { @@ -423,6 +449,11 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 // NOTE(bill): The first arg may be a Type, this will be checked case by case break; + case BuiltinProc_atomic_thread_fence: + case BuiltinProc_atomic_signal_fence: + // NOTE(bill): first type will require a type hint + break; + case BuiltinProc_DIRECTIVE: { ast_node(bd, BasicDirective, ce->proc); String name = bd->name.string; @@ -3198,10 +3229,12 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 break; - case BuiltinProc_atomic_fence: - case BuiltinProc_atomic_fence_acq: - case BuiltinProc_atomic_fence_rel: - case BuiltinProc_atomic_fence_acqrel: + + case BuiltinProc_atomic_thread_fence: + case BuiltinProc_atomic_signal_fence: + if (!check_atomic_memory_order_argument(c, ce->args[0], builtin_name)) { + return false; + } operand->mode = Addressing_NoValue; break; @@ -3210,9 +3243,6 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 case BuiltinProc_unaligned_store: /*fallthrough*/ case BuiltinProc_atomic_store: - case BuiltinProc_atomic_store_rel: - case BuiltinProc_atomic_store_relaxed: - case BuiltinProc_atomic_store_unordered: { Type *elem = nullptr; if (!is_type_normal_pointer(operand->type, &elem)) { @@ -3228,14 +3258,32 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 break; } + case BuiltinProc_atomic_store_explicit: + { + Type *elem = nullptr; + if (!is_type_normal_pointer(operand->type, &elem)) { + error(operand->expr, "Expected a pointer for '%.*s'", LIT(builtin_name)); + return false; + } + Operand x = {}; + check_expr_with_type_hint(c, &x, ce->args[1], elem); + check_assignment(c, &x, elem, builtin_name); + + if (!check_atomic_memory_order_argument(c, ce->args[2], builtin_name)) { + return false; + } + + operand->type = nullptr; + operand->mode = Addressing_NoValue; + break; + } + + case BuiltinProc_volatile_load: /*fallthrough*/ case BuiltinProc_unaligned_load: /*fallthrough*/ case BuiltinProc_atomic_load: - case BuiltinProc_atomic_load_acq: - case BuiltinProc_atomic_load_relaxed: - case BuiltinProc_atomic_load_unordered: { Type *elem = nullptr; if (!is_type_normal_pointer(operand->type, &elem)) { @@ -3247,41 +3295,52 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 break; } + case BuiltinProc_atomic_load_explicit: + { + Type *elem = nullptr; + if (!is_type_normal_pointer(operand->type, &elem)) { + error(operand->expr, "Expected a pointer for '%.*s'", LIT(builtin_name)); + return false; + } + + if (!check_atomic_memory_order_argument(c, ce->args[1], builtin_name)) { + return false; + } + + operand->type = elem; + operand->mode = Addressing_Value; + break; + } + case BuiltinProc_atomic_add: - case BuiltinProc_atomic_add_acq: - case BuiltinProc_atomic_add_rel: - case BuiltinProc_atomic_add_acqrel: - case BuiltinProc_atomic_add_relaxed: case BuiltinProc_atomic_sub: - case BuiltinProc_atomic_sub_acq: - case BuiltinProc_atomic_sub_rel: - case BuiltinProc_atomic_sub_acqrel: - case BuiltinProc_atomic_sub_relaxed: case BuiltinProc_atomic_and: - case BuiltinProc_atomic_and_acq: - case BuiltinProc_atomic_and_rel: - case BuiltinProc_atomic_and_acqrel: - case BuiltinProc_atomic_and_relaxed: case BuiltinProc_atomic_nand: - case BuiltinProc_atomic_nand_acq: - case BuiltinProc_atomic_nand_rel: - case BuiltinProc_atomic_nand_acqrel: - case BuiltinProc_atomic_nand_relaxed: case BuiltinProc_atomic_or: - case BuiltinProc_atomic_or_acq: - case BuiltinProc_atomic_or_rel: - case BuiltinProc_atomic_or_acqrel: - case BuiltinProc_atomic_or_relaxed: case BuiltinProc_atomic_xor: - case BuiltinProc_atomic_xor_acq: - case BuiltinProc_atomic_xor_rel: - case BuiltinProc_atomic_xor_acqrel: - case BuiltinProc_atomic_xor_relaxed: - case BuiltinProc_atomic_xchg: - case BuiltinProc_atomic_xchg_acq: - case BuiltinProc_atomic_xchg_rel: - case BuiltinProc_atomic_xchg_acqrel: - case BuiltinProc_atomic_xchg_relaxed: + case BuiltinProc_atomic_exchange: + { + Type *elem = nullptr; + if (!is_type_normal_pointer(operand->type, &elem)) { + error(operand->expr, "Expected a pointer for '%.*s'", LIT(builtin_name)); + return false; + } + Operand x = {}; + check_expr_with_type_hint(c, &x, ce->args[1], elem); + check_assignment(c, &x, elem, builtin_name); + + operand->type = elem; + operand->mode = Addressing_Value; + break; + } + + case BuiltinProc_atomic_add_explicit: + case BuiltinProc_atomic_sub_explicit: + case BuiltinProc_atomic_and_explicit: + case BuiltinProc_atomic_nand_explicit: + case BuiltinProc_atomic_or_explicit: + case BuiltinProc_atomic_xor_explicit: + case BuiltinProc_atomic_exchange_explicit: { Type *elem = nullptr; if (!is_type_normal_pointer(operand->type, &elem)) { @@ -3292,30 +3351,18 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 check_expr_with_type_hint(c, &x, ce->args[1], elem); check_assignment(c, &x, elem, builtin_name); + + if (!check_atomic_memory_order_argument(c, ce->args[2], builtin_name)) { + return false; + } + operand->type = elem; operand->mode = Addressing_Value; break; } - case BuiltinProc_atomic_cxchg: - case BuiltinProc_atomic_cxchg_acq: - case BuiltinProc_atomic_cxchg_rel: - case BuiltinProc_atomic_cxchg_acqrel: - case BuiltinProc_atomic_cxchg_relaxed: - case BuiltinProc_atomic_cxchg_failrelaxed: - case BuiltinProc_atomic_cxchg_failacq: - case BuiltinProc_atomic_cxchg_acq_failrelaxed: - case BuiltinProc_atomic_cxchg_acqrel_failrelaxed: - - case BuiltinProc_atomic_cxchgweak: - case BuiltinProc_atomic_cxchgweak_acq: - case BuiltinProc_atomic_cxchgweak_rel: - case BuiltinProc_atomic_cxchgweak_acqrel: - case BuiltinProc_atomic_cxchgweak_relaxed: - case BuiltinProc_atomic_cxchgweak_failrelaxed: - case BuiltinProc_atomic_cxchgweak_failacq: - case BuiltinProc_atomic_cxchgweak_acq_failrelaxed: - case BuiltinProc_atomic_cxchgweak_acqrel_failrelaxed: + case BuiltinProc_atomic_compare_exchange_strong: + case BuiltinProc_atomic_compare_exchange_weak: { Type *elem = nullptr; if (!is_type_normal_pointer(operand->type, &elem)) { @@ -3333,7 +3380,33 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 operand->type = elem; break; } - break; + + case BuiltinProc_atomic_compare_exchange_strong_explicit: + case BuiltinProc_atomic_compare_exchange_weak_explicit: + { + Type *elem = nullptr; + if (!is_type_normal_pointer(operand->type, &elem)) { + error(operand->expr, "Expected a pointer for '%.*s'", LIT(builtin_name)); + return false; + } + Operand x = {}; + Operand y = {}; + check_expr_with_type_hint(c, &x, ce->args[1], elem); + check_expr_with_type_hint(c, &y, ce->args[2], elem); + check_assignment(c, &x, elem, builtin_name); + check_assignment(c, &y, elem, builtin_name); + + if (!check_atomic_memory_order_argument(c, ce->args[3], builtin_name, "success ordering")) { + return false; + } + if (!check_atomic_memory_order_argument(c, ce->args[4], builtin_name, "failure ordering")) { + return false; + } + + operand->mode = Addressing_OptionalOk; + operand->type = elem; + break; + } case BuiltinProc_fixed_point_mul: case BuiltinProc_fixed_point_div: diff --git a/src/checker.cpp b/src/checker.cpp index 53bba654d..0c72a8e14 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -829,15 +829,16 @@ struct GlobalEnumValue { i64 value; }; -Slice add_global_enum_type(String const &type_name, GlobalEnumValue *values, isize value_count) { +Slice add_global_enum_type(String const &type_name, GlobalEnumValue *values, isize value_count, Type **enum_type_ = nullptr) { Scope *scope = create_scope(nullptr, builtin_pkg->scope); - Entity *e = alloc_entity_type_name(scope, make_token_ident(type_name), nullptr, EntityState_Resolved); + Entity *entity = alloc_entity_type_name(scope, make_token_ident(type_name), nullptr, EntityState_Resolved); Type *enum_type = alloc_type_enum(); - Type *named_type = alloc_type_named(type_name, enum_type, e); + Type *named_type = alloc_type_named(type_name, enum_type, entity); set_base_type(named_type, enum_type); enum_type->Enum.base_type = t_int; enum_type->Enum.scope = scope; + entity->type = named_type; auto fields = array_make(permanent_allocator(), value_count); for (isize i = 0; i < value_count; i++) { @@ -858,6 +859,9 @@ Slice add_global_enum_type(String const &type_name, GlobalEnumValue *v enum_type->Enum.min_value = &enum_type->Enum.fields[enum_type->Enum.min_value_index]->Constant.value; enum_type->Enum.max_value = &enum_type->Enum.fields[enum_type->Enum.max_value_index]->Constant.value; + + if (enum_type_) *enum_type_ = named_type; + return slice_from_array(fields); } void add_global_enum_constant(Slice const &fields, char const *name, i64 value) { @@ -986,6 +990,21 @@ void init_universal(void) { add_global_enum_constant(fields, "ODIN_ERROR_POS_STYLE", build_context.ODIN_ERROR_POS_STYLE); } + { + GlobalEnumValue values[OdinAtomicMemoryOrder_COUNT] = { + {"relaxed", OdinAtomicMemoryOrder_relaxed}, + {"consume", OdinAtomicMemoryOrder_consume}, + {"acquire", OdinAtomicMemoryOrder_acquire}, + {"release", OdinAtomicMemoryOrder_release}, + {"acq_rel", OdinAtomicMemoryOrder_acq_rel}, + {"seq_cst", OdinAtomicMemoryOrder_seq_cst}, + }; + + add_global_enum_type(str_lit("Atomic_Memory_Order"), values, gb_count_of(values), &t_atomic_memory_order); + GB_ASSERT(t_atomic_memory_order->kind == Type_Named); + scope_insert(intrinsics_pkg->scope, t_atomic_memory_order->Named.type_name); + } + add_global_bool_constant("ODIN_DEBUG", bc->ODIN_DEBUG); add_global_bool_constant("ODIN_DISABLE_ASSERT", bc->ODIN_DISABLE_ASSERT); diff --git a/src/checker_builtin_procs.hpp b/src/checker_builtin_procs.hpp index c647d5a01..c6b0afee0 100644 --- a/src/checker_builtin_procs.hpp +++ b/src/checker_builtin_procs.hpp @@ -86,77 +86,30 @@ enum BuiltinProcId { BuiltinProc_prefetch_write_instruction, BuiltinProc_prefetch_write_data, - BuiltinProc_atomic_fence, - BuiltinProc_atomic_fence_acq, - BuiltinProc_atomic_fence_rel, - BuiltinProc_atomic_fence_acqrel, - + BuiltinProc_atomic_thread_fence, + BuiltinProc_atomic_signal_fence, BuiltinProc_atomic_store, - BuiltinProc_atomic_store_rel, - BuiltinProc_atomic_store_relaxed, - BuiltinProc_atomic_store_unordered, - + BuiltinProc_atomic_store_explicit, BuiltinProc_atomic_load, - BuiltinProc_atomic_load_acq, - BuiltinProc_atomic_load_relaxed, - BuiltinProc_atomic_load_unordered, - + BuiltinProc_atomic_load_explicit, BuiltinProc_atomic_add, - BuiltinProc_atomic_add_acq, - BuiltinProc_atomic_add_rel, - BuiltinProc_atomic_add_acqrel, - BuiltinProc_atomic_add_relaxed, + BuiltinProc_atomic_add_explicit, BuiltinProc_atomic_sub, - BuiltinProc_atomic_sub_acq, - BuiltinProc_atomic_sub_rel, - BuiltinProc_atomic_sub_acqrel, - BuiltinProc_atomic_sub_relaxed, + BuiltinProc_atomic_sub_explicit, BuiltinProc_atomic_and, - BuiltinProc_atomic_and_acq, - BuiltinProc_atomic_and_rel, - BuiltinProc_atomic_and_acqrel, - BuiltinProc_atomic_and_relaxed, + BuiltinProc_atomic_and_explicit, BuiltinProc_atomic_nand, - BuiltinProc_atomic_nand_acq, - BuiltinProc_atomic_nand_rel, - BuiltinProc_atomic_nand_acqrel, - BuiltinProc_atomic_nand_relaxed, + BuiltinProc_atomic_nand_explicit, BuiltinProc_atomic_or, - BuiltinProc_atomic_or_acq, - BuiltinProc_atomic_or_rel, - BuiltinProc_atomic_or_acqrel, - BuiltinProc_atomic_or_relaxed, + BuiltinProc_atomic_or_explicit, BuiltinProc_atomic_xor, - BuiltinProc_atomic_xor_acq, - BuiltinProc_atomic_xor_rel, - BuiltinProc_atomic_xor_acqrel, - BuiltinProc_atomic_xor_relaxed, - - BuiltinProc_atomic_xchg, - BuiltinProc_atomic_xchg_acq, - BuiltinProc_atomic_xchg_rel, - BuiltinProc_atomic_xchg_acqrel, - BuiltinProc_atomic_xchg_relaxed, - - BuiltinProc_atomic_cxchg, - BuiltinProc_atomic_cxchg_acq, - BuiltinProc_atomic_cxchg_rel, - BuiltinProc_atomic_cxchg_acqrel, - BuiltinProc_atomic_cxchg_relaxed, - BuiltinProc_atomic_cxchg_failrelaxed, - BuiltinProc_atomic_cxchg_failacq, - BuiltinProc_atomic_cxchg_acq_failrelaxed, - BuiltinProc_atomic_cxchg_acqrel_failrelaxed, - - BuiltinProc_atomic_cxchgweak, - BuiltinProc_atomic_cxchgweak_acq, - BuiltinProc_atomic_cxchgweak_rel, - BuiltinProc_atomic_cxchgweak_acqrel, - BuiltinProc_atomic_cxchgweak_relaxed, - BuiltinProc_atomic_cxchgweak_failrelaxed, - BuiltinProc_atomic_cxchgweak_failacq, - BuiltinProc_atomic_cxchgweak_acq_failrelaxed, - BuiltinProc_atomic_cxchgweak_acqrel_failrelaxed, + BuiltinProc_atomic_xor_explicit, + BuiltinProc_atomic_exchange, + BuiltinProc_atomic_exchange_explicit, + BuiltinProc_atomic_compare_exchange_strong, + BuiltinProc_atomic_compare_exchange_strong_explicit, + BuiltinProc_atomic_compare_exchange_weak, + BuiltinProc_atomic_compare_exchange_weak_explicit, BuiltinProc_fixed_point_mul, BuiltinProc_fixed_point_div, @@ -352,78 +305,30 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = { {STR_LIT("prefetch_write_instruction"), 2, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, {STR_LIT("prefetch_write_data"), 2, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_fence"), 0, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_fence_acq"), 0, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_fence_rel"), 0, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_fence_acqrel"), 0, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, - - {STR_LIT("atomic_store"), 2, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_store_rel"), 2, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_store_relaxed"), 2, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_store_unordered"), 2, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, - - {STR_LIT("atomic_load"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_load_acq"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_load_relaxed"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_load_unordered"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - - {STR_LIT("atomic_add"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_add_acq"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_add_rel"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_add_acqrel"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_add_relaxed"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_sub"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_sub_acq"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_sub_rel"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_sub_acqrel"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_sub_relaxed"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_and"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_and_acq"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_and_rel"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_and_acqrel"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_and_relaxed"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_nand"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_nand_acq"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_nand_rel"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_nand_acqrel"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_nand_relaxed"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_or"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_or_acq"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_or_rel"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_or_acqrel"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_or_relaxed"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_xor"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_xor_acq"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_xor_rel"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_xor_acqrel"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_xor_relaxed"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - - {STR_LIT("atomic_xchg"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_xchg_acq"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_xchg_rel"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_xchg_acqrel"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_xchg_relaxed"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - - {STR_LIT("atomic_cxchg"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_cxchg_acq"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_cxchg_rel"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_cxchg_acqrel"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_cxchg_relaxed"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_cxchg_failrelaxed"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_cxchg_failacq"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_cxchg_acq_failrelaxed"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_cxchg_acqrel_failrelaxed"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - - {STR_LIT("atomic_cxchgweak"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_cxchgweak_acq"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_cxchgweak_rel"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_cxchgweak_acqrel"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_cxchgweak_relaxed"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_cxchgweak_failrelaxed"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_cxchgweak_failacq"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_cxchgweak_acq_failrelaxed"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_cxchgweak_acqrel_failrelaxed"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - + {STR_LIT("atomic_thread_fence"), 1, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, + {STR_LIT("atomic_signal_fence"), 1, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, + {STR_LIT("atomic_store"), 2, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, + {STR_LIT("atomic_store_explicit"), 3, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, + {STR_LIT("atomic_load"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("atomic_load_explicit"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("atomic_add"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("atomic_add_explicit"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("atomic_sub"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("atomic_sub_explicit"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("atomic_and"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("atomic_and_explicit"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("atomic_nand"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("atomic_nand_explicit"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("atomic_or"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("atomic_or_explicit"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("atomic_xor"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("atomic_xor_explicit"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("atomic_exchange"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("atomic_exchange_explicit"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("atomic_compare_exchange_strong"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("atomic_compare_exchange_strong_explicit"), 5, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("atomic_compare_exchange_weak"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("atomic_compare_exchange_weak_explicit"), 5, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("fixed_point_mul"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("fixed_point_div"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index d7f3d6c45..ad82b79e5 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -1606,36 +1606,26 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, } - - case BuiltinProc_atomic_fence: - LLVMBuildFence(p->builder, LLVMAtomicOrderingSequentiallyConsistent, false, ""); - return {}; - case BuiltinProc_atomic_fence_acq: - LLVMBuildFence(p->builder, LLVMAtomicOrderingAcquire, false, ""); - return {}; - case BuiltinProc_atomic_fence_rel: - LLVMBuildFence(p->builder, LLVMAtomicOrderingRelease, false, ""); + // TODO(bill): Which is correct? + case BuiltinProc_atomic_thread_fence: + LLVMBuildFence(p->builder, llvm_atomic_ordering_from_odin(ce->args[0]), false, ""); return {}; - case BuiltinProc_atomic_fence_acqrel: - LLVMBuildFence(p->builder, LLVMAtomicOrderingAcquireRelease, false, ""); + case BuiltinProc_atomic_signal_fence: + LLVMBuildFence(p->builder, llvm_atomic_ordering_from_odin(ce->args[0]), true, ""); return {}; case BuiltinProc_volatile_store: case BuiltinProc_atomic_store: - case BuiltinProc_atomic_store_rel: - case BuiltinProc_atomic_store_relaxed: - case BuiltinProc_atomic_store_unordered: { + case BuiltinProc_atomic_store_explicit: { lbValue dst = lb_build_expr(p, ce->args[0]); lbValue val = lb_build_expr(p, ce->args[1]); val = lb_emit_conv(p, val, type_deref(dst.type)); LLVMValueRef instr = LLVMBuildStore(p->builder, val.value, dst.value); switch (id) { - case BuiltinProc_volatile_store: LLVMSetVolatile(instr, true); break; - case BuiltinProc_atomic_store: LLVMSetOrdering(instr, LLVMAtomicOrderingSequentiallyConsistent); break; - case BuiltinProc_atomic_store_rel: LLVMSetOrdering(instr, LLVMAtomicOrderingRelease); break; - case BuiltinProc_atomic_store_relaxed: LLVMSetOrdering(instr, LLVMAtomicOrderingMonotonic); break; - case BuiltinProc_atomic_store_unordered: LLVMSetOrdering(instr, LLVMAtomicOrderingUnordered); break; + case BuiltinProc_volatile_store: LLVMSetVolatile(instr, true); break; + case BuiltinProc_atomic_store: LLVMSetOrdering(instr, LLVMAtomicOrderingSequentiallyConsistent); break; + case BuiltinProc_atomic_store_explicit: LLVMSetOrdering(instr, llvm_atomic_ordering_from_odin(ce->args[2])); break; } LLVMSetAlignment(instr, cast(unsigned)type_align_of(type_deref(dst.type))); @@ -1645,18 +1635,14 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, case BuiltinProc_volatile_load: case BuiltinProc_atomic_load: - case BuiltinProc_atomic_load_acq: - case BuiltinProc_atomic_load_relaxed: - case BuiltinProc_atomic_load_unordered: { + case BuiltinProc_atomic_load_explicit: { lbValue dst = lb_build_expr(p, ce->args[0]); LLVMValueRef instr = LLVMBuildLoad(p->builder, dst.value, ""); switch (id) { - case BuiltinProc_volatile_load: LLVMSetVolatile(instr, true); break; - case BuiltinProc_atomic_load: LLVMSetOrdering(instr, LLVMAtomicOrderingSequentiallyConsistent); break; - case BuiltinProc_atomic_load_acq: LLVMSetOrdering(instr, LLVMAtomicOrderingAcquire); break; - case BuiltinProc_atomic_load_relaxed: LLVMSetOrdering(instr, LLVMAtomicOrderingMonotonic); break; - case BuiltinProc_atomic_load_unordered: LLVMSetOrdering(instr, LLVMAtomicOrderingUnordered); break; + case BuiltinProc_volatile_load: LLVMSetVolatile(instr, true); break; + case BuiltinProc_atomic_load: LLVMSetOrdering(instr, LLVMAtomicOrderingSequentiallyConsistent); break; + case BuiltinProc_atomic_load_explicit: LLVMSetOrdering(instr, llvm_atomic_ordering_from_odin(ce->args[1])); break; } LLVMSetAlignment(instr, cast(unsigned)type_align_of(type_deref(dst.type))); @@ -1686,40 +1672,19 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, } case BuiltinProc_atomic_add: - case BuiltinProc_atomic_add_acq: - case BuiltinProc_atomic_add_rel: - case BuiltinProc_atomic_add_acqrel: - case BuiltinProc_atomic_add_relaxed: case BuiltinProc_atomic_sub: - case BuiltinProc_atomic_sub_acq: - case BuiltinProc_atomic_sub_rel: - case BuiltinProc_atomic_sub_acqrel: - case BuiltinProc_atomic_sub_relaxed: case BuiltinProc_atomic_and: - case BuiltinProc_atomic_and_acq: - case BuiltinProc_atomic_and_rel: - case BuiltinProc_atomic_and_acqrel: - case BuiltinProc_atomic_and_relaxed: case BuiltinProc_atomic_nand: - case BuiltinProc_atomic_nand_acq: - case BuiltinProc_atomic_nand_rel: - case BuiltinProc_atomic_nand_acqrel: - case BuiltinProc_atomic_nand_relaxed: case BuiltinProc_atomic_or: - case BuiltinProc_atomic_or_acq: - case BuiltinProc_atomic_or_rel: - case BuiltinProc_atomic_or_acqrel: - case BuiltinProc_atomic_or_relaxed: case BuiltinProc_atomic_xor: - case BuiltinProc_atomic_xor_acq: - case BuiltinProc_atomic_xor_rel: - case BuiltinProc_atomic_xor_acqrel: - case BuiltinProc_atomic_xor_relaxed: - case BuiltinProc_atomic_xchg: - case BuiltinProc_atomic_xchg_acq: - case BuiltinProc_atomic_xchg_rel: - case BuiltinProc_atomic_xchg_acqrel: - case BuiltinProc_atomic_xchg_relaxed: { + case BuiltinProc_atomic_exchange: + case BuiltinProc_atomic_add_explicit: + case BuiltinProc_atomic_sub_explicit: + case BuiltinProc_atomic_and_explicit: + case BuiltinProc_atomic_nand_explicit: + case BuiltinProc_atomic_or_explicit: + case BuiltinProc_atomic_xor_explicit: + case BuiltinProc_atomic_exchange_explicit: { lbValue dst = lb_build_expr(p, ce->args[0]); lbValue val = lb_build_expr(p, ce->args[1]); val = lb_emit_conv(p, val, type_deref(dst.type)); @@ -1728,41 +1693,20 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, LLVMAtomicOrdering ordering = {}; switch (id) { - case BuiltinProc_atomic_add: op = LLVMAtomicRMWBinOpAdd; ordering = LLVMAtomicOrderingSequentiallyConsistent; break; - case BuiltinProc_atomic_add_acq: op = LLVMAtomicRMWBinOpAdd; ordering = LLVMAtomicOrderingAcquire; break; - case BuiltinProc_atomic_add_rel: op = LLVMAtomicRMWBinOpAdd; ordering = LLVMAtomicOrderingRelease; break; - case BuiltinProc_atomic_add_acqrel: op = LLVMAtomicRMWBinOpAdd; ordering = LLVMAtomicOrderingAcquireRelease; break; - case BuiltinProc_atomic_add_relaxed: op = LLVMAtomicRMWBinOpAdd; ordering = LLVMAtomicOrderingMonotonic; break; - case BuiltinProc_atomic_sub: op = LLVMAtomicRMWBinOpSub; ordering = LLVMAtomicOrderingSequentiallyConsistent; break; - case BuiltinProc_atomic_sub_acq: op = LLVMAtomicRMWBinOpSub; ordering = LLVMAtomicOrderingAcquire; break; - case BuiltinProc_atomic_sub_rel: op = LLVMAtomicRMWBinOpSub; ordering = LLVMAtomicOrderingRelease; break; - case BuiltinProc_atomic_sub_acqrel: op = LLVMAtomicRMWBinOpSub; ordering = LLVMAtomicOrderingAcquireRelease; break; - case BuiltinProc_atomic_sub_relaxed: op = LLVMAtomicRMWBinOpSub; ordering = LLVMAtomicOrderingMonotonic; break; - case BuiltinProc_atomic_and: op = LLVMAtomicRMWBinOpAnd; ordering = LLVMAtomicOrderingSequentiallyConsistent; break; - case BuiltinProc_atomic_and_acq: op = LLVMAtomicRMWBinOpAnd; ordering = LLVMAtomicOrderingAcquire; break; - case BuiltinProc_atomic_and_rel: op = LLVMAtomicRMWBinOpAnd; ordering = LLVMAtomicOrderingRelease; break; - case BuiltinProc_atomic_and_acqrel: op = LLVMAtomicRMWBinOpAnd; ordering = LLVMAtomicOrderingAcquireRelease; break; - case BuiltinProc_atomic_and_relaxed: op = LLVMAtomicRMWBinOpAnd; ordering = LLVMAtomicOrderingMonotonic; break; - case BuiltinProc_atomic_nand: op = LLVMAtomicRMWBinOpNand; ordering = LLVMAtomicOrderingSequentiallyConsistent; break; - case BuiltinProc_atomic_nand_acq: op = LLVMAtomicRMWBinOpNand; ordering = LLVMAtomicOrderingAcquire; break; - case BuiltinProc_atomic_nand_rel: op = LLVMAtomicRMWBinOpNand; ordering = LLVMAtomicOrderingRelease; break; - case BuiltinProc_atomic_nand_acqrel: op = LLVMAtomicRMWBinOpNand; ordering = LLVMAtomicOrderingAcquireRelease; break; - case BuiltinProc_atomic_nand_relaxed: op = LLVMAtomicRMWBinOpNand; ordering = LLVMAtomicOrderingMonotonic; break; - case BuiltinProc_atomic_or: op = LLVMAtomicRMWBinOpOr; ordering = LLVMAtomicOrderingSequentiallyConsistent; break; - case BuiltinProc_atomic_or_acq: op = LLVMAtomicRMWBinOpOr; ordering = LLVMAtomicOrderingAcquire; break; - case BuiltinProc_atomic_or_rel: op = LLVMAtomicRMWBinOpOr; ordering = LLVMAtomicOrderingRelease; break; - case BuiltinProc_atomic_or_acqrel: op = LLVMAtomicRMWBinOpOr; ordering = LLVMAtomicOrderingAcquireRelease; break; - case BuiltinProc_atomic_or_relaxed: op = LLVMAtomicRMWBinOpOr; ordering = LLVMAtomicOrderingMonotonic; break; - case BuiltinProc_atomic_xor: op = LLVMAtomicRMWBinOpXor; ordering = LLVMAtomicOrderingSequentiallyConsistent; break; - case BuiltinProc_atomic_xor_acq: op = LLVMAtomicRMWBinOpXor; ordering = LLVMAtomicOrderingAcquire; break; - case BuiltinProc_atomic_xor_rel: op = LLVMAtomicRMWBinOpXor; ordering = LLVMAtomicOrderingRelease; break; - case BuiltinProc_atomic_xor_acqrel: op = LLVMAtomicRMWBinOpXor; ordering = LLVMAtomicOrderingAcquireRelease; break; - case BuiltinProc_atomic_xor_relaxed: op = LLVMAtomicRMWBinOpXor; ordering = LLVMAtomicOrderingMonotonic; break; - case BuiltinProc_atomic_xchg: op = LLVMAtomicRMWBinOpXchg; ordering = LLVMAtomicOrderingSequentiallyConsistent; break; - case BuiltinProc_atomic_xchg_acq: op = LLVMAtomicRMWBinOpXchg; ordering = LLVMAtomicOrderingAcquire; break; - case BuiltinProc_atomic_xchg_rel: op = LLVMAtomicRMWBinOpXchg; ordering = LLVMAtomicOrderingRelease; break; - case BuiltinProc_atomic_xchg_acqrel: op = LLVMAtomicRMWBinOpXchg; ordering = LLVMAtomicOrderingAcquireRelease; break; - case BuiltinProc_atomic_xchg_relaxed: op = LLVMAtomicRMWBinOpXchg; ordering = LLVMAtomicOrderingMonotonic; break; + case BuiltinProc_atomic_add: op = LLVMAtomicRMWBinOpAdd; ordering = LLVMAtomicOrderingSequentiallyConsistent; break; + case BuiltinProc_atomic_sub: op = LLVMAtomicRMWBinOpSub; ordering = LLVMAtomicOrderingSequentiallyConsistent; break; + case BuiltinProc_atomic_and: op = LLVMAtomicRMWBinOpAnd; ordering = LLVMAtomicOrderingSequentiallyConsistent; break; + case BuiltinProc_atomic_nand: op = LLVMAtomicRMWBinOpNand; ordering = LLVMAtomicOrderingSequentiallyConsistent; break; + case BuiltinProc_atomic_or: op = LLVMAtomicRMWBinOpOr; ordering = LLVMAtomicOrderingSequentiallyConsistent; break; + case BuiltinProc_atomic_xor: op = LLVMAtomicRMWBinOpXor; ordering = LLVMAtomicOrderingSequentiallyConsistent; break; + case BuiltinProc_atomic_exchange: op = LLVMAtomicRMWBinOpXchg; ordering = LLVMAtomicOrderingSequentiallyConsistent; break; + case BuiltinProc_atomic_add_explicit: op = LLVMAtomicRMWBinOpAdd; ordering = llvm_atomic_ordering_from_odin(ce->args[2]); break; + case BuiltinProc_atomic_sub_explicit: op = LLVMAtomicRMWBinOpSub; ordering = llvm_atomic_ordering_from_odin(ce->args[2]); break; + case BuiltinProc_atomic_and_explicit: op = LLVMAtomicRMWBinOpAnd; ordering = llvm_atomic_ordering_from_odin(ce->args[2]); break; + case BuiltinProc_atomic_nand_explicit: op = LLVMAtomicRMWBinOpNand; ordering = llvm_atomic_ordering_from_odin(ce->args[2]); break; + case BuiltinProc_atomic_or_explicit: op = LLVMAtomicRMWBinOpOr; ordering = llvm_atomic_ordering_from_odin(ce->args[2]); break; + case BuiltinProc_atomic_xor_explicit: op = LLVMAtomicRMWBinOpXor; ordering = llvm_atomic_ordering_from_odin(ce->args[2]); break; + case BuiltinProc_atomic_exchange_explicit: op = LLVMAtomicRMWBinOpXchg; ordering = llvm_atomic_ordering_from_odin(ce->args[2]); break; } lbValue res = {}; @@ -1771,24 +1715,10 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, return res; } - case BuiltinProc_atomic_cxchg: - case BuiltinProc_atomic_cxchg_acq: - case BuiltinProc_atomic_cxchg_rel: - case BuiltinProc_atomic_cxchg_acqrel: - case BuiltinProc_atomic_cxchg_relaxed: - case BuiltinProc_atomic_cxchg_failrelaxed: - case BuiltinProc_atomic_cxchg_failacq: - case BuiltinProc_atomic_cxchg_acq_failrelaxed: - case BuiltinProc_atomic_cxchg_acqrel_failrelaxed: - case BuiltinProc_atomic_cxchgweak: - case BuiltinProc_atomic_cxchgweak_acq: - case BuiltinProc_atomic_cxchgweak_rel: - case BuiltinProc_atomic_cxchgweak_acqrel: - case BuiltinProc_atomic_cxchgweak_relaxed: - case BuiltinProc_atomic_cxchgweak_failrelaxed: - case BuiltinProc_atomic_cxchgweak_failacq: - case BuiltinProc_atomic_cxchgweak_acq_failrelaxed: - case BuiltinProc_atomic_cxchgweak_acqrel_failrelaxed: { + case BuiltinProc_atomic_compare_exchange_strong: + case BuiltinProc_atomic_compare_exchange_weak: + case BuiltinProc_atomic_compare_exchange_strong_explicit: + case BuiltinProc_atomic_compare_exchange_weak_explicit: { lbValue address = lb_build_expr(p, ce->args[0]); Type *elem = type_deref(address.type); lbValue old_value = lb_build_expr(p, ce->args[1]); @@ -1801,24 +1731,10 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, LLVMBool weak = false; switch (id) { - case BuiltinProc_atomic_cxchg: success_ordering = LLVMAtomicOrderingSequentiallyConsistent; failure_ordering = LLVMAtomicOrderingSequentiallyConsistent; weak = false; break; - case BuiltinProc_atomic_cxchg_acq: success_ordering = LLVMAtomicOrderingAcquire; failure_ordering = LLVMAtomicOrderingMonotonic; weak = false; break; - case BuiltinProc_atomic_cxchg_rel: success_ordering = LLVMAtomicOrderingRelease; failure_ordering = LLVMAtomicOrderingMonotonic; weak = false; break; - case BuiltinProc_atomic_cxchg_acqrel: success_ordering = LLVMAtomicOrderingAcquireRelease; failure_ordering = LLVMAtomicOrderingMonotonic; weak = false; break; - case BuiltinProc_atomic_cxchg_relaxed: success_ordering = LLVMAtomicOrderingMonotonic; failure_ordering = LLVMAtomicOrderingMonotonic; weak = false; break; - case BuiltinProc_atomic_cxchg_failrelaxed: success_ordering = LLVMAtomicOrderingSequentiallyConsistent; failure_ordering = LLVMAtomicOrderingMonotonic; weak = false; break; - case BuiltinProc_atomic_cxchg_failacq: success_ordering = LLVMAtomicOrderingSequentiallyConsistent; failure_ordering = LLVMAtomicOrderingAcquire; weak = false; break; - case BuiltinProc_atomic_cxchg_acq_failrelaxed: success_ordering = LLVMAtomicOrderingAcquire; failure_ordering = LLVMAtomicOrderingMonotonic; weak = false; break; - case BuiltinProc_atomic_cxchg_acqrel_failrelaxed: success_ordering = LLVMAtomicOrderingAcquireRelease; failure_ordering = LLVMAtomicOrderingMonotonic; weak = false; break; - case BuiltinProc_atomic_cxchgweak: success_ordering = LLVMAtomicOrderingSequentiallyConsistent; failure_ordering = LLVMAtomicOrderingSequentiallyConsistent; weak = false; break; - case BuiltinProc_atomic_cxchgweak_acq: success_ordering = LLVMAtomicOrderingAcquire; failure_ordering = LLVMAtomicOrderingMonotonic; weak = true; break; - case BuiltinProc_atomic_cxchgweak_rel: success_ordering = LLVMAtomicOrderingRelease; failure_ordering = LLVMAtomicOrderingMonotonic; weak = true; break; - case BuiltinProc_atomic_cxchgweak_acqrel: success_ordering = LLVMAtomicOrderingAcquireRelease; failure_ordering = LLVMAtomicOrderingMonotonic; weak = true; break; - case BuiltinProc_atomic_cxchgweak_relaxed: success_ordering = LLVMAtomicOrderingMonotonic; failure_ordering = LLVMAtomicOrderingMonotonic; weak = true; break; - case BuiltinProc_atomic_cxchgweak_failrelaxed: success_ordering = LLVMAtomicOrderingSequentiallyConsistent; failure_ordering = LLVMAtomicOrderingMonotonic; weak = true; break; - case BuiltinProc_atomic_cxchgweak_failacq: success_ordering = LLVMAtomicOrderingSequentiallyConsistent; failure_ordering = LLVMAtomicOrderingAcquire; weak = true; break; - case BuiltinProc_atomic_cxchgweak_acq_failrelaxed: success_ordering = LLVMAtomicOrderingAcquire; failure_ordering = LLVMAtomicOrderingMonotonic; weak = true; break; - case BuiltinProc_atomic_cxchgweak_acqrel_failrelaxed: success_ordering = LLVMAtomicOrderingAcquireRelease; failure_ordering = LLVMAtomicOrderingMonotonic; weak = true; break; + case BuiltinProc_atomic_compare_exchange_strong: success_ordering = LLVMAtomicOrderingSequentiallyConsistent; failure_ordering = LLVMAtomicOrderingSequentiallyConsistent; weak = false; break; + case BuiltinProc_atomic_compare_exchange_weak: success_ordering = LLVMAtomicOrderingSequentiallyConsistent; failure_ordering = LLVMAtomicOrderingSequentiallyConsistent; weak = true; break; + case BuiltinProc_atomic_compare_exchange_strong_explicit: success_ordering = llvm_atomic_ordering_from_odin(ce->args[3]); failure_ordering = llvm_atomic_ordering_from_odin(ce->args[4]); weak = false; break; + case BuiltinProc_atomic_compare_exchange_weak_explicit: success_ordering = llvm_atomic_ordering_from_odin(ce->args[3]); failure_ordering = llvm_atomic_ordering_from_odin(ce->args[4]); weak = true; break; } // TODO(bill): Figure out how to make it weak diff --git a/src/llvm_backend_utility.cpp b/src/llvm_backend_utility.cpp index 399d1632d..037171637 100644 --- a/src/llvm_backend_utility.cpp +++ b/src/llvm_backend_utility.cpp @@ -2005,3 +2005,25 @@ lbValue lb_handle_objc_send(lbProcedure *p, Ast *expr) { } + + +LLVMAtomicOrdering llvm_atomic_ordering_from_odin(ExactValue const &value) { + GB_ASSERT(value.kind == ExactValue_Integer); + i64 v = exact_value_to_i64(value); + switch (v) { + case OdinAtomicMemoryOrder_relaxed: return LLVMAtomicOrderingUnordered; + case OdinAtomicMemoryOrder_consume: return LLVMAtomicOrderingMonotonic; + case OdinAtomicMemoryOrder_acquire: return LLVMAtomicOrderingAcquire; + case OdinAtomicMemoryOrder_release: return LLVMAtomicOrderingRelease; + case OdinAtomicMemoryOrder_acq_rel: return LLVMAtomicOrderingAcquireRelease; + case OdinAtomicMemoryOrder_seq_cst: return LLVMAtomicOrderingSequentiallyConsistent; + } + GB_PANIC("Unknown atomic ordering"); + return LLVMAtomicOrderingSequentiallyConsistent; +} + + +LLVMAtomicOrdering llvm_atomic_ordering_from_odin(Ast *expr) { + ExactValue value = type_and_value_of_expr(expr).value; + return llvm_atomic_ordering_from_odin(value); +} diff --git a/src/types.cpp b/src/types.cpp index b231218a2..25e29820c 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -692,6 +692,19 @@ gb_global Type *t_objc_id = nullptr; gb_global Type *t_objc_SEL = nullptr; gb_global Type *t_objc_Class = nullptr; +enum OdinAtomicMemoryOrder : i32 { + OdinAtomicMemoryOrder_relaxed = 0, + OdinAtomicMemoryOrder_consume = 1, + OdinAtomicMemoryOrder_acquire = 2, + OdinAtomicMemoryOrder_release = 3, + OdinAtomicMemoryOrder_acq_rel = 4, + OdinAtomicMemoryOrder_seq_cst = 5, + OdinAtomicMemoryOrder_COUNT, +}; + +gb_global Type *t_atomic_memory_order = nullptr; + + gb_global RecursiveMutex g_type_mutex; -- cgit v1.2.3 From 9f2d710c357f9d1ca28c169269a9816e1788d1b1 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 31 Mar 2022 12:57:24 +0100 Subject: Change `intrinsics.Atomic_Memory_Order` fields to use `Ada_Case` rather than `snake_case` --- core/c/libc/stdatomic.odin | 150 ++++++++++++++++++------------------- core/intrinsics/intrinsics.odin | 12 +-- core/mem/mem.odin | 2 +- core/sync/atomic.odin | 12 +-- core/sync/extended.odin | 30 ++++---- core/sync/primitives_atomic.odin | 16 ++-- core/sync/primitives_internal.odin | 6 +- src/checker.cpp | 12 +-- src/types.cpp | 12 +-- 9 files changed, 126 insertions(+), 126 deletions(-) (limited to 'src/checker.cpp') diff --git a/core/c/libc/stdatomic.odin b/core/c/libc/stdatomic.odin index 26ea0db5e..9de3c4678 100644 --- a/core/c/libc/stdatomic.odin +++ b/core/c/libc/stdatomic.odin @@ -50,10 +50,10 @@ atomic_thread_fence :: #force_inline proc(order: memory_order) { assert(order != .relaxed) assert(order != .consume) #partial switch order { - case .acquire: intrinsics.atomic_thread_fence(.acquire) - case .release: intrinsics.atomic_thread_fence(.release) - case .acq_rel: intrinsics.atomic_thread_fence(.acq_rel) - case .seq_cst: intrinsics.atomic_thread_fence(.seq_cst) + case .acquire: intrinsics.atomic_thread_fence(.Acquire) + case .release: intrinsics.atomic_thread_fence(.Release) + case .acq_rel: intrinsics.atomic_thread_fence(.Acq_Rel) + case .seq_cst: intrinsics.atomic_thread_fence(.Seq_Cst) } } @@ -61,10 +61,10 @@ atomic_signal_fence :: #force_inline proc(order: memory_order) { assert(order != .relaxed) assert(order != .consume) #partial switch order { - case .acquire: intrinsics.atomic_signal_fence(.acquire) - case .release: intrinsics.atomic_signal_fence(.release) - case .acq_rel: intrinsics.atomic_signal_fence(.acq_rel) - case .seq_cst: intrinsics.atomic_signal_fence(.seq_cst) + case .acquire: intrinsics.atomic_signal_fence(.Acquire) + case .release: intrinsics.atomic_signal_fence(.Release) + case .acq_rel: intrinsics.atomic_signal_fence(.Acq_Rel) + case .seq_cst: intrinsics.atomic_signal_fence(.Seq_Cst) } } @@ -123,9 +123,9 @@ atomic_store_explicit :: #force_inline proc(object: ^$T, desired: T, order: memo assert(order != .acq_rel) #partial switch order { - case .relaxed: intrinsics.atomic_store_explicit(object, desired, .relaxed) - case .release: intrinsics.atomic_store_explicit(object, desired, .release) - case .seq_cst: intrinsics.atomic_store_explicit(object, desired, .seq_cst) + case .relaxed: intrinsics.atomic_store_explicit(object, desired, .Relaxed) + case .release: intrinsics.atomic_store_explicit(object, desired, .Release) + case .seq_cst: intrinsics.atomic_store_explicit(object, desired, .Seq_Cst) } } @@ -138,10 +138,10 @@ atomic_load_explicit :: #force_inline proc(object: ^$T, order: memory_order) { assert(order != .acq_rel) #partial switch order { - case .relaxed: return intrinsics.atomic_load_explicit(object, .relaxed) - case .consume: return intrinsics.atomic_load_explicit(object, .consume) - case .acquire: return intrinsics.atomic_load_explicit(object, .acquire) - case .seq_cst: return intrinsics.atomic_load_explicit(object, .seq_cst) + case .relaxed: return intrinsics.atomic_load_explicit(object, .Relaxed) + case .consume: return intrinsics.atomic_load_explicit(object, .Consume) + case .acquire: return intrinsics.atomic_load_explicit(object, .Acquire) + case .seq_cst: return intrinsics.atomic_load_explicit(object, .Seq_Cst) } } @@ -151,12 +151,12 @@ atomic_exchange :: #force_inline proc(object: ^$T, desired: T) -> T { atomic_exchange_explicit :: #force_inline proc(object: ^$T, desired: T, order: memory_order) -> T { switch order { - case .relaxed: return intrinsics.atomic_exchange_explicit(object, desired, .relaxed) - case .consume: return intrinsics.atomic_exchange_explicit(object, desired, .consume) - case .acquire: return intrinsics.atomic_exchange_explicit(object, desired, .acquire) - case .release: return intrinsics.atomic_exchange_explicit(object, desired, .release) - case .acq_rel: return intrinsics.atomic_exchange_explicit(object, desired, .acq_rel) - case .seq_cst: return intrinsics.atomic_exchange_explicit(object, desired, .seq_cst) + case .relaxed: return intrinsics.atomic_exchange_explicit(object, desired, .Relaxed) + case .consume: return intrinsics.atomic_exchange_explicit(object, desired, .Consume) + case .acquire: return intrinsics.atomic_exchange_explicit(object, desired, .Acquire) + case .release: return intrinsics.atomic_exchange_explicit(object, desired, .Release) + case .acq_rel: return intrinsics.atomic_exchange_explicit(object, desired, .Acq_Rel) + case .seq_cst: return intrinsics.atomic_exchange_explicit(object, desired, .Seq_Cst) } return false } @@ -193,36 +193,36 @@ atomic_compare_exchange_strong_explicit :: #force_inline proc(object, expected: assert(success != .relaxed) #partial switch success { case .seq_cst: - value, ok = intrinsics.atomic_compare_exchange_strong_explicit(object, expected^, desired, .seq_cst, .seq_cst) + value, ok = intrinsics.atomic_compare_exchange_strong_explicit(object, expected^, desired, .Seq_Cst, .Seq_Cst) case .acquire: - value, ok = intrinsics.atomic_compare_exchange_strong_explicit(object, expected^, desired, .acquire, .seq_cst) + value, ok = intrinsics.atomic_compare_exchange_strong_explicit(object, expected^, desired, .Acquire, .Seq_Cst) case .consume: - value, ok = intrinsics.atomic_compare_exchange_strong_explicit(object, expected^, desired, .consume, .seq_cst) + value, ok = intrinsics.atomic_compare_exchange_strong_explicit(object, expected^, desired, .Consume, .Seq_Cst) case .release: - value, ok = intrinsics.atomic_compare_exchange_strong_explicit(object, expected^, desired, .release, .seq_cst) + value, ok = intrinsics.atomic_compare_exchange_strong_explicit(object, expected^, desired, .Release, .Seq_Cst) case .acq_rel: - value, ok = intrinsics.atomic_compare_exchange_strong_explicit(object, expected^, desired, .acq_rel, .seq_cst) + value, ok = intrinsics.atomic_compare_exchange_strong_explicit(object, expected^, desired, .Acq_Rel, .Seq_Cst) } case .relaxed: assert(success != .release) #partial switch success { case .relaxed: - value, ok = intrinsics.atomic_compare_exchange_strong_explicit(object, expected^, desired, .relaxed, .relaxed) + value, ok = intrinsics.atomic_compare_exchange_strong_explicit(object, expected^, desired, .Relaxed, .Relaxed) case .seq_cst: - value, ok = intrinsics.atomic_compare_exchange_strong_explicit(object, expected^, desired, .seq_cst, .relaxed) + value, ok = intrinsics.atomic_compare_exchange_strong_explicit(object, expected^, desired, .Seq_Cst, .Relaxed) case .acquire: - value, ok = intrinsics.atomic_compare_exchange_strong_explicit(object, expected^, desired, .acquire, .relaxed) + value, ok = intrinsics.atomic_compare_exchange_strong_explicit(object, expected^, desired, .Acquire, .Relaxed) case .consume: - value, ok = intrinsics.atomic_compare_exchange_strong_explicit(object, expected^, desired, .consume, .relaxed) + value, ok = intrinsics.atomic_compare_exchange_strong_explicit(object, expected^, desired, .Consume, .Relaxed) case .acq_rel: - value, ok = intrinsics.atomic_compare_exchange_strong_explicit(object, expected^, desired, .acq_rel, .relaxed) + value, ok = intrinsics.atomic_compare_exchange_strong_explicit(object, expected^, desired, .Acq_Rel, .Relaxed) } case .consume: assert(success == .seq_cst) - value, ok = intrinsics.atomic_compare_exchange_strong_explicit(object, expected^, desired, .seq_cst, .consume) + value, ok = intrinsics.atomic_compare_exchange_strong_explicit(object, expected^, desired, .Seq_Cst, .Consume) case .acquire: assert(success == .seq_cst) - value, ok = intrinsics.atomic_compare_exchange_strong_explicit(object, expected^, desired, .seq_cst, .acquire) + value, ok = intrinsics.atomic_compare_exchange_strong_explicit(object, expected^, desired, .Seq_Cst, .Acquire) } if !ok { expected^ = value } @@ -245,36 +245,36 @@ atomic_compare_exchange_weak_explicit :: #force_inline proc(object, expected: ^$ assert(success != .relaxed) #partial switch success { case .seq_cst: - value, ok = intrinsics.atomic_compare_exchange_weak_explicit(object, expected^, desired, .seq_cst, .seq_cst) + value, ok = intrinsics.atomic_compare_exchange_weak_explicit(object, expected^, desired, .Seq_Cst, .Seq_Cst) case .acquire: - value, ok = intrinsics.atomic_compare_exchange_weak_explicit(object, expected^, desired, .acquire, .seq_cst) + value, ok = intrinsics.atomic_compare_exchange_weak_explicit(object, expected^, desired, .Acquire, .Seq_Cst) case .consume: - value, ok = intrinsics.atomic_compare_exchange_weak_explicit(object, expected^, desired, .consume, .seq_cst) + value, ok = intrinsics.atomic_compare_exchange_weak_explicit(object, expected^, desired, .Consume, .Seq_Cst) case .release: - value, ok = intrinsics.atomic_compare_exchange_weak_explicit(object, expected^, desired, .release, .seq_cst) + value, ok = intrinsics.atomic_compare_exchange_weak_explicit(object, expected^, desired, .Release, .Seq_Cst) case .acq_rel: - value, ok = intrinsics.atomic_compare_exchange_weak_explicit(object, expected^, desired, .acq_rel, .seq_cst) + value, ok = intrinsics.atomic_compare_exchange_weak_explicit(object, expected^, desired, .Acq_Rel, .Seq_Cst) } case .relaxed: assert(success != .release) #partial switch success { case .relaxed: - value, ok = intrinsics.atomic_compare_exchange_weak_explicit(object, expected^, desired, .relaxed, .relaxed) + value, ok = intrinsics.atomic_compare_exchange_weak_explicit(object, expected^, desired, .Relaxed, .Relaxed) case .seq_cst: - value, ok = intrinsics.atomic_compare_exchange_weak_explicit(object, expected^, desired, .seq_cst, .relaxed) + value, ok = intrinsics.atomic_compare_exchange_weak_explicit(object, expected^, desired, .Seq_Cst, .Relaxed) case .acquire: - value, ok = intrinsics.atomic_compare_exchange_weak_explicit(object, expected^, desired, .acquire, .relaxed) + value, ok = intrinsics.atomic_compare_exchange_weak_explicit(object, expected^, desired, .Acquire, .Relaxed) case .consume: - value, ok = intrinsics.atomic_compare_exchange_weak_explicit(object, expected^, desired, .consume, .relaxed) + value, ok = intrinsics.atomic_compare_exchange_weak_explicit(object, expected^, desired, .Consume, .Relaxed) case .acq_rel: - value, ok = intrinsics.atomic_compare_exchange_weak_explicit(object, expected^, desired, .acq_rel, .relaxed) + value, ok = intrinsics.atomic_compare_exchange_weak_explicit(object, expected^, desired, .Acq_Rel, .Relaxed) } case .consume: assert(success == .seq_cst) - value, ok = intrinsics.atomic_compare_exchange_weak_explicit(object, expected^, desired, .seq_cst, .consume) + value, ok = intrinsics.atomic_compare_exchange_weak_explicit(object, expected^, desired, .Seq_Cst, .Consume) case .acquire: assert(success == .seq_cst) - value, ok = intrinsics.atomic_compare_exchange_weak_explicit(object, expected^, desired, .seq_cst, .acquire) + value, ok = intrinsics.atomic_compare_exchange_weak_explicit(object, expected^, desired, .Seq_Cst, .Acquire) } if !ok { expected^ = value } @@ -288,13 +288,13 @@ atomic_fetch_add :: #force_inline proc(object: ^$T, operand: T) -> T { atomic_fetch_add_explicit :: #force_inline proc(object: ^$T, operand: T, order: memory_order) -> T { switch order { - case .relaxed: return intrinsics.atomic_add_explicit(object, operand, .relaxed) - case .consume: return intrinsics.atomic_add_explicit(object, operand, .consume) - case .acquire: return intrinsics.atomic_add_explicit(object, operand, .acquire) - case .release: return intrinsics.atomic_add_explicit(object, operand, .release) - case .acq_rel: return intrinsics.atomic_add_explicit(object, operand, .acq_rel) + case .relaxed: return intrinsics.atomic_add_explicit(object, operand, .Relaxed) + case .consume: return intrinsics.atomic_add_explicit(object, operand, .Consume) + case .acquire: return intrinsics.atomic_add_explicit(object, operand, .Acquire) + case .release: return intrinsics.atomic_add_explicit(object, operand, .Release) + case .acq_rel: return intrinsics.atomic_add_explicit(object, operand, .Acq_Rel) case: fallthrough - case .seq_cst: return intrinsics.atomic_add_explicit(object, operand, .seq_cst) + case .seq_cst: return intrinsics.atomic_add_explicit(object, operand, .Seq_Cst) } } @@ -304,13 +304,13 @@ atomic_fetch_sub :: #force_inline proc(object: ^$T, operand: T) -> T { atomic_fetch_sub_explicit :: #force_inline proc(object: ^$T, operand: T, order: memory_order) -> T { switch order { - case .relaxed: return intrinsics.atomic_sub_explicit(object, operand, .relaxed) - case .consume: return intrinsics.atomic_sub_explicit(object, operand, .consume) - case .acquire: return intrinsics.atomic_sub_explicit(object, operand, .acquire) - case .release: return intrinsics.atomic_sub_explicit(object, operand, .release) - case .acq_rel: return intrinsics.atomic_sub_explicit(object, operand, .acq_rel) + case .relaxed: return intrinsics.atomic_sub_explicit(object, operand, .Relaxed) + case .consume: return intrinsics.atomic_sub_explicit(object, operand, .Consume) + case .acquire: return intrinsics.atomic_sub_explicit(object, operand, .Acquire) + case .release: return intrinsics.atomic_sub_explicit(object, operand, .Release) + case .acq_rel: return intrinsics.atomic_sub_explicit(object, operand, .Acq_Rel) case: fallthrough - case .seq_cst: return intrinsics.atomic_sub_explicit(object, operand, .seq_cst) + case .seq_cst: return intrinsics.atomic_sub_explicit(object, operand, .Seq_Cst) } } @@ -320,13 +320,13 @@ atomic_fetch_or :: #force_inline proc(object: ^$T, operand: T) -> T { atomic_fetch_or_explicit :: #force_inline proc(object: ^$T, operand: T, order: memory_order) -> T { switch order { - case .relaxed: return intrinsics.atomic_or_explicit(object, operand, .relaxed) - case .consume: return intrinsics.atomic_or_explicit(object, operand, .consume) - case .acquire: return intrinsics.atomic_or_explicit(object, operand, .acquire) - case .release: return intrinsics.atomic_or_explicit(object, operand, .release) - case .acq_rel: return intrinsics.atomic_or_explicit(object, operand, .acq_rel) + case .relaxed: return intrinsics.atomic_or_explicit(object, operand, .Relaxed) + case .consume: return intrinsics.atomic_or_explicit(object, operand, .Consume) + case .acquire: return intrinsics.atomic_or_explicit(object, operand, .Acquire) + case .release: return intrinsics.atomic_or_explicit(object, operand, .Release) + case .acq_rel: return intrinsics.atomic_or_explicit(object, operand, .Acq_Rel) case: fallthrough - case .seq_cst: return intrinsics.atomic_or_explicit(object, operand, .seq_cst) + case .seq_cst: return intrinsics.atomic_or_explicit(object, operand, .Seq_Cst) } } @@ -336,13 +336,13 @@ atomic_fetch_xor :: #force_inline proc(object: ^$T, operand: T) -> T { atomic_fetch_xor_explicit :: #force_inline proc(object: ^$T, operand: T, order: memory_order) -> T { switch order { - case .relaxed: return intrinsics.atomic_xor_explicit(object, operand, .relaxed) - case .consume: return intrinsics.atomic_xor_explicit(object, operand, .consume) - case .acquire: return intrinsics.atomic_xor_explicit(object, operand, .acquire) - case .release: return intrinsics.atomic_xor_explicit(object, operand, .release) - case .acq_rel: return intrinsics.atomic_xor_explicit(object, operand, .acq_rel) + case .relaxed: return intrinsics.atomic_xor_explicit(object, operand, .Relaxed) + case .consume: return intrinsics.atomic_xor_explicit(object, operand, .Consume) + case .acquire: return intrinsics.atomic_xor_explicit(object, operand, .Acquire) + case .release: return intrinsics.atomic_xor_explicit(object, operand, .Release) + case .acq_rel: return intrinsics.atomic_xor_explicit(object, operand, .Acq_Rel) case: fallthrough - case .seq_cst: return intrinsics.atomic_xor_explicit(object, operand, .seq_cst) + case .seq_cst: return intrinsics.atomic_xor_explicit(object, operand, .Seq_Cst) } } @@ -351,13 +351,13 @@ atomic_fetch_and :: #force_inline proc(object: ^$T, operand: T) -> T { } atomic_fetch_and_explicit :: #force_inline proc(object: ^$T, operand: T, order: memory_order) -> T { switch order { - case .relaxed: return intrinsics.atomic_and_explicit(object, operand, .relaxed) - case .consume: return intrinsics.atomic_and_explicit(object, operand, .consume) - case .acquire: return intrinsics.atomic_and_explicit(object, operand, .acquire) - case .release: return intrinsics.atomic_and_explicit(object, operand, .release) - case .acq_rel: return intrinsics.atomic_and_explicit(object, operand, .acq_rel) + case .relaxed: return intrinsics.atomic_and_explicit(object, operand, .Relaxed) + case .consume: return intrinsics.atomic_and_explicit(object, operand, .Consume) + case .acquire: return intrinsics.atomic_and_explicit(object, operand, .Acquire) + case .release: return intrinsics.atomic_and_explicit(object, operand, .Release) + case .acq_rel: return intrinsics.atomic_and_explicit(object, operand, .Acq_Rel) case: fallthrough - case .seq_cst: return intrinsics.atomic_and_explicit(object, operand, .seq_cst) + case .seq_cst: return intrinsics.atomic_and_explicit(object, operand, .Seq_Cst) } } diff --git a/core/intrinsics/intrinsics.odin b/core/intrinsics/intrinsics.odin index 4c1c166e6..ce8fd96ea 100644 --- a/core/intrinsics/intrinsics.odin +++ b/core/intrinsics/intrinsics.odin @@ -63,12 +63,12 @@ syscall :: proc(id: uintptr, args: ..uintptr) -> uintptr --- // Atomics Atomic_Memory_Order :: enum { - relaxed = 0, // unordered - consume = 1, // monotonic - acquire = 2, - release = 3, - acq_rel = 4, - seq_cst = 5, + Relaxed = 0, // Unordered + Consume = 1, // Monotonic + Acquire = 2, + Release = 3, + Acq_Rel = 4, + Seq_Cst = 5, } atomic_thread_fence :: proc(order: Atomic_Memory_Order) --- diff --git a/core/mem/mem.odin b/core/mem/mem.odin index 1ebe558ef..817c0ea5f 100644 --- a/core/mem/mem.odin +++ b/core/mem/mem.odin @@ -16,7 +16,7 @@ zero_explicit :: proc "contextless" (data: rawptr, len: int) -> rawptr { // equivalent semantics to those provided by the C11 Annex K 3.7.4.1 // memset_s call. intrinsics.mem_zero_volatile(data, len) // Use the volatile mem_zero - intrinsics.atomic_thread_fence(.seq_cst) // Prevent reordering + intrinsics.atomic_thread_fence(.Seq_Cst) // Prevent reordering return data } zero_item :: proc "contextless" (item: $P/^$T) { diff --git a/core/sync/atomic.odin b/core/sync/atomic.odin index d6521daed..f537764c4 100644 --- a/core/sync/atomic.odin +++ b/core/sync/atomic.odin @@ -6,12 +6,12 @@ cpu_relax :: intrinsics.cpu_relax /* Atomic_Memory_Order :: enum { - relaxed = 0, - consume = 1, - acquire = 2, - release = 3, - acq_rel = 4, - seq_cst = 5, + Relaxed = 0, + Consume = 1, + Acquire = 2, + Release = 3, + Acq_Rel = 4, + Seq_Cst = 5, } */ Atomic_Memory_Order :: intrinsics.Atomic_Memory_Order diff --git a/core/sync/extended.odin b/core/sync/extended.odin index c8ae4493f..24f7c096c 100644 --- a/core/sync/extended.odin +++ b/core/sync/extended.odin @@ -146,10 +146,10 @@ Auto_Reset_Event :: struct { } auto_reset_event_signal :: proc(e: ^Auto_Reset_Event) { - old_status := atomic_load_explicit(&e.status, .relaxed) + old_status := atomic_load_explicit(&e.status, .Relaxed) for { new_status := old_status + 1 if old_status < 1 else 1 - if _, ok := atomic_compare_exchange_weak_explicit(&e.status, old_status, new_status, .release, .relaxed); ok { + if _, ok := atomic_compare_exchange_weak_explicit(&e.status, old_status, new_status, .Release, .Relaxed); ok { break } @@ -160,7 +160,7 @@ auto_reset_event_signal :: proc(e: ^Auto_Reset_Event) { } auto_reset_event_wait :: proc(e: ^Auto_Reset_Event) { - old_status := atomic_sub_explicit(&e.status, 1, .acquire) + old_status := atomic_sub_explicit(&e.status, 1, .Acquire) if old_status < 1 { sema_wait(&e.sema) } @@ -174,14 +174,14 @@ Ticket_Mutex :: struct { } ticket_mutex_lock :: #force_inline proc(m: ^Ticket_Mutex) { - ticket := atomic_add_explicit(&m.ticket, 1, .relaxed) - for ticket != atomic_load_explicit(&m.serving, .acquire) { + ticket := atomic_add_explicit(&m.ticket, 1, .Relaxed) + for ticket != atomic_load_explicit(&m.serving, .Acquire) { cpu_relax() } } ticket_mutex_unlock :: #force_inline proc(m: ^Ticket_Mutex) { - atomic_add_explicit(&m.serving, 1, .relaxed) + atomic_add_explicit(&m.serving, 1, .Relaxed) } @(deferred_in=ticket_mutex_unlock) ticket_mutex_guard :: proc(m: ^Ticket_Mutex) -> bool { @@ -196,18 +196,18 @@ Benaphore :: struct { } benaphore_lock :: proc(b: ^Benaphore) { - if atomic_add_explicit(&b.counter, 1, .acquire) > 1 { + if atomic_add_explicit(&b.counter, 1, .Acquire) > 1 { sema_wait(&b.sema) } } benaphore_try_lock :: proc(b: ^Benaphore) -> bool { - v, _ := atomic_compare_exchange_strong_explicit(&b.counter, 1, 0, .acquire, .acquire) + v, _ := atomic_compare_exchange_strong_explicit(&b.counter, 1, 0, .Acquire, .Acquire) return v == 0 } benaphore_unlock :: proc(b: ^Benaphore) { - if atomic_sub_explicit(&b.counter, 1, .release) > 0 { + if atomic_sub_explicit(&b.counter, 1, .Release) > 0 { sema_post(&b.sema) } } @@ -227,7 +227,7 @@ Recursive_Benaphore :: struct { recursive_benaphore_lock :: proc(b: ^Recursive_Benaphore) { tid := current_thread_id() - if atomic_add_explicit(&b.counter, 1, .acquire) > 1 { + if atomic_add_explicit(&b.counter, 1, .Acquire) > 1 { if tid != b.owner { sema_wait(&b.sema) } @@ -240,10 +240,10 @@ recursive_benaphore_lock :: proc(b: ^Recursive_Benaphore) { recursive_benaphore_try_lock :: proc(b: ^Recursive_Benaphore) -> bool { tid := current_thread_id() if b.owner == tid { - atomic_add_explicit(&b.counter, 1, .acquire) + atomic_add_explicit(&b.counter, 1, .Acquire) } - if v, _ := atomic_compare_exchange_strong_explicit(&b.counter, 1, 0, .acquire, .acquire); v != 0 { + if v, _ := atomic_compare_exchange_strong_explicit(&b.counter, 1, 0, .Acquire, .Acquire); v != 0 { return false } // inside the lock @@ -260,7 +260,7 @@ recursive_benaphore_unlock :: proc(b: ^Recursive_Benaphore) { if recursion == 0 { b.owner = 0 } - if atomic_sub_explicit(&b.counter, 1, .release) > 0 { + if atomic_sub_explicit(&b.counter, 1, .Release) > 0 { if recursion == 0 { sema_post(&b.sema) } @@ -293,12 +293,12 @@ once_do :: proc(o: ^Once, fn: proc()) { defer mutex_unlock(&o.m) if !o.done { fn() - atomic_store_explicit(&o.done, true, .release) + atomic_store_explicit(&o.done, true, .Release) } } - if atomic_load_explicit(&o.done, .acquire) == false { + if atomic_load_explicit(&o.done, .Acquire) == false { do_slow(o, fn) } } diff --git a/core/sync/primitives_atomic.odin b/core/sync/primitives_atomic.odin index 401f78b91..11fff4e60 100644 --- a/core/sync/primitives_atomic.odin +++ b/core/sync/primitives_atomic.odin @@ -24,7 +24,7 @@ atomic_mutex_lock :: proc(m: ^Atomic_Mutex) { new_state := curr_state // Make a copy of it spin_lock: for spin in 0.. bool { - _, ok := atomic_compare_exchange_strong_explicit(&m.state, .Unlocked, .Locked, .acquire, .consume) + _, ok := atomic_compare_exchange_strong_explicit(&m.state, .Unlocked, .Locked, .Acquire, .Consume) return ok } @@ -290,7 +290,7 @@ Queue_Item :: struct { @(private="file") queue_item_wait :: proc(item: ^Queue_Item) { - for atomic_load_explicit(&item.futex, .acquire) == 0 { + for atomic_load_explicit(&item.futex, .Acquire) == 0 { futex_wait(&item.futex, 0) cpu_relax() } @@ -298,7 +298,7 @@ queue_item_wait :: proc(item: ^Queue_Item) { @(private="file") queue_item_wait_with_timeout :: proc(item: ^Queue_Item, duration: time.Duration) -> bool { start := time.tick_now() - for atomic_load_explicit(&item.futex, .acquire) == 0 { + for atomic_load_explicit(&item.futex, .Acquire) == 0 { remaining := duration - time.tick_since(start) if remaining < 0 { return false @@ -312,7 +312,7 @@ queue_item_wait_with_timeout :: proc(item: ^Queue_Item, duration: time.Duration) } @(private="file") queue_item_signal :: proc(item: ^Queue_Item) { - atomic_store_explicit(&item.futex, 1, .release) + atomic_store_explicit(&item.futex, 1, .Release) futex_signal(&item.futex) } diff --git a/core/sync/primitives_internal.odin b/core/sync/primitives_internal.odin index c1a38b4ad..4807b41c1 100644 --- a/core/sync/primitives_internal.odin +++ b/core/sync/primitives_internal.odin @@ -10,7 +10,7 @@ when #config(ODIN_SYNC_RECURSIVE_MUTEX_USE_FUTEX, true) { _recursive_mutex_lock :: proc(m: ^Recursive_Mutex) { tid := Futex(current_thread_id()) for { - prev_owner := atomic_compare_exchange_strong_explicit(&m.impl.owner, tid, 0, .acquire, .acquire) + prev_owner := atomic_compare_exchange_strong_explicit(&m.impl.owner, tid, 0, .Acquire, .Acquire) switch prev_owner { case 0, tid: m.impl.recursion += 1 @@ -27,7 +27,7 @@ when #config(ODIN_SYNC_RECURSIVE_MUTEX_USE_FUTEX, true) { if m.impl.recursion != 0 { return } - atomic_exchange_explicit(&m.impl.owner, 0, .release) + atomic_exchange_explicit(&m.impl.owner, 0, .Release) futex_signal(&m.impl.owner) // outside the lock @@ -36,7 +36,7 @@ when #config(ODIN_SYNC_RECURSIVE_MUTEX_USE_FUTEX, true) { _recursive_mutex_try_lock :: proc(m: ^Recursive_Mutex) -> bool { tid := Futex(current_thread_id()) - prev_owner := atomic_compare_exchange_strong_explicit(&m.impl.owner, tid, 0, .acquire, .acquire) + prev_owner := atomic_compare_exchange_strong_explicit(&m.impl.owner, tid, 0, .Acquire, .Acquire) switch prev_owner { case 0, tid: m.impl.recursion += 1 diff --git a/src/checker.cpp b/src/checker.cpp index 0c72a8e14..1bb786ea1 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -992,12 +992,12 @@ void init_universal(void) { { GlobalEnumValue values[OdinAtomicMemoryOrder_COUNT] = { - {"relaxed", OdinAtomicMemoryOrder_relaxed}, - {"consume", OdinAtomicMemoryOrder_consume}, - {"acquire", OdinAtomicMemoryOrder_acquire}, - {"release", OdinAtomicMemoryOrder_release}, - {"acq_rel", OdinAtomicMemoryOrder_acq_rel}, - {"seq_cst", OdinAtomicMemoryOrder_seq_cst}, + {OdinAtomicMemoryOrder_strings[OdinAtomicMemoryOrder_relaxed], OdinAtomicMemoryOrder_relaxed}, + {OdinAtomicMemoryOrder_strings[OdinAtomicMemoryOrder_consume], OdinAtomicMemoryOrder_consume}, + {OdinAtomicMemoryOrder_strings[OdinAtomicMemoryOrder_acquire], OdinAtomicMemoryOrder_acquire}, + {OdinAtomicMemoryOrder_strings[OdinAtomicMemoryOrder_release], OdinAtomicMemoryOrder_release}, + {OdinAtomicMemoryOrder_strings[OdinAtomicMemoryOrder_acq_rel], OdinAtomicMemoryOrder_acq_rel}, + {OdinAtomicMemoryOrder_strings[OdinAtomicMemoryOrder_seq_cst], OdinAtomicMemoryOrder_seq_cst}, }; add_global_enum_type(str_lit("Atomic_Memory_Order"), values, gb_count_of(values), &t_atomic_memory_order); diff --git a/src/types.cpp b/src/types.cpp index 16d07d392..e10dae1ed 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -703,12 +703,12 @@ enum OdinAtomicMemoryOrder : i32 { }; char const *OdinAtomicMemoryOrder_strings[OdinAtomicMemoryOrder_COUNT] = { - "relaxed", - "consume", - "acquire", - "release", - "acq_rel", - "seq_cst", + "Relaxed", + "Consume", + "Acquire", + "Release", + "Acq_Rel", + "Seq_Cst", }; gb_global Type *t_atomic_memory_order = nullptr; -- cgit v1.2.3