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/check_decl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/check_decl.cpp') 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) { -- 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/check_decl.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/check_decl.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 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/check_decl.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/check_decl.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/check_decl.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 1553137c2365c3980488a6455fd83f0fcb9e28ca Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 5 Feb 2022 00:04:02 +0000 Subject: Change behaviour of `A :: distinct Enum_Type` to be more intuitive --- src/check_decl.cpp | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) (limited to 'src/check_decl.cpp') diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 63fc777c0..f6dade812 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -238,6 +238,51 @@ isize total_attribute_count(DeclInfo *decl) { return attribute_count; } +Type *clone_enum_type(CheckerContext *ctx, Type *original_enum_type, Type *named_type) { + // NOTE(bill, 2022-02-05): Stupid edge case for `distinct` declarations + // + // X :: enum {A, B, C} + // Y :: distinct X + // + // To make Y be just like X, it will need to copy the elements of X and change their type + // so that they match Y rather than X. + GB_ASSERT(original_enum_type != nullptr); + GB_ASSERT(named_type != nullptr); + GB_ASSERT(original_enum_type->kind == Type_Enum); + GB_ASSERT(named_type->kind == Type_Named); + + Scope *parent = original_enum_type->Enum.scope->parent; + Scope *scope = create_scope(nullptr, parent); + + + Type *et = alloc_type_enum(); + et->Enum.base_type = original_enum_type->Enum.base_type; + et->Enum.min_value = original_enum_type->Enum.min_value; + et->Enum.max_value = original_enum_type->Enum.max_value; + et->Enum.min_value_index = original_enum_type->Enum.min_value_index; + et->Enum.max_value_index = original_enum_type->Enum.max_value_index; + et->Enum.scope = scope; + + auto fields = array_make(permanent_allocator(), original_enum_type->Enum.fields.count); + for_array(i, fields) { + Entity *old = original_enum_type->Enum.fields[i]; + + Entity *e = alloc_entity_constant(scope, old->token, named_type, old->Constant.value); + e->file = old->file; + e->identifier = clone_ast(old->identifier); + e->flags |= EntityFlag_Visited; + e->state = EntityState_Resolved; + e->Constant.flags = old->Constant.flags; + e->Constant.docs = old->Constant.docs; + e->Constant.comment = old->Constant.comment; + + fields[i] = e; + add_entity(ctx, scope, nullptr, e); + add_entity_use(ctx, e->identifier, e); + } + et->Enum.fields = fields; + return et; +} void check_type_decl(CheckerContext *ctx, Entity *e, Ast *init_expr, Type *def) { GB_ASSERT(e->type == nullptr); @@ -258,7 +303,11 @@ void check_type_decl(CheckerContext *ctx, Entity *e, Ast *init_expr, Type *def) Type *bt = check_type_expr(ctx, te, named); check_type_path_pop(ctx); - named->Named.base = base_type(bt); + Type *base = base_type(bt); + if (is_distinct && bt->kind == Type_Named && base->kind == Type_Enum) { + base = clone_enum_type(ctx, base, named); + } + named->Named.base = base; if (is_distinct && is_type_typeid(e->type)) { error(init_expr, "'distinct' cannot be applied to 'typeid'"); -- 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/check_decl.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/check_decl.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/check_decl.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 7681c43b144015278b75b2788b824a5630f6ccd6 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 28 Feb 2022 12:12:04 +0000 Subject: Show error message when something like this is done `test: proc() : {}` --- src/check_decl.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/check_decl.cpp') diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 45d741532..3fdd944f9 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -174,6 +174,10 @@ void check_init_constant(CheckerContext *ctx, Entity *e, Operand *operand) { return; } + if (is_type_proc(e->type)) { + error(e->token, "Illegal declaration of a constant procedure value"); + } + e->parent_proc_decl = ctx->curr_proc_decl; e->Constant.value = operand->value; -- 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/check_decl.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 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/check_decl.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 286549693eb2e7b216effba01d9aa192eab78d12 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 14 Mar 2022 12:28:28 +0000 Subject: Fix `#1609` --- src/check_decl.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/check_decl.cpp') diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 12b0e43cb..d4a320f03 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -440,6 +440,12 @@ void check_const_decl(CheckerContext *ctx, Entity *e, Ast *type_expr, Ast *init, if (type_expr) { e->type = check_type(ctx, type_expr); + if (are_types_identical(e->type, t_typeid)) { + e->type = nullptr; + e->kind = Entity_TypeName; + check_type_decl(ctx, e, init, named_type); + return; + } } Operand operand = {}; -- cgit v1.2.3 From 72ae0617694593aecf4b3d0006f2786d7ad4dea6 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 30 Mar 2022 17:29:37 +0100 Subject: Add `intrinsics.wasm_memory_grow` `intrinsics.wasm_memory_size` --- core/intrinsics/intrinsics.odin | 4 +++ src/check_builtin.cpp | 69 ++++++++++++++++++++++++++++++++++++++++- src/check_decl.cpp | 4 ++- src/checker_builtin_procs.hpp | 4 +++ src/llvm_backend_proc.cpp | 39 +++++++++++++++++++++++ 5 files changed, 118 insertions(+), 2 deletions(-) (limited to 'src/check_decl.cpp') diff --git a/core/intrinsics/intrinsics.odin b/core/intrinsics/intrinsics.odin index c3ef787bc..16dd5cbc5 100644 --- a/core/intrinsics/intrinsics.odin +++ b/core/intrinsics/intrinsics.odin @@ -201,6 +201,10 @@ type_equal_proc :: proc($T: typeid) -> (equal: proc "contextless" (rawptr, raw type_hasher_proc :: proc($T: typeid) -> (hasher: proc "contextless" (data: rawptr, seed: uintptr) -> uintptr) where type_is_comparable(T) --- +// WASM targets only +wasm_memory_grow :: proc(index, delta: uintptr) -> int --- +wasm_memory_size :: proc(index: uintptr) -> int --- + // Internal compiler use only __entry_point :: proc() --- \ No newline at end of file diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index 4cd09b8e9..e480704e3 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -304,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' 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", LIT(builtin_name), e, t); gb_string_free(t); gb_string_free(e); return false; @@ -4111,6 +4111,73 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 } + case BuiltinProc_wasm_memory_grow: + { + if (!is_arch_wasm()) { + error(call, "'%.*s' is only allowed on wasm targets", LIT(builtin_name)); + return false; + } + + Operand index = {}; + Operand delta = {}; + check_expr(c, &index, ce->args[0]); if (index.mode == Addressing_Invalid) return false; + check_expr(c, &delta, ce->args[1]); if (delta.mode == Addressing_Invalid) return false; + + convert_to_typed(c, &index, t_uintptr); if (index.mode == Addressing_Invalid) return false; + convert_to_typed(c, &delta, t_uintptr); if (delta.mode == Addressing_Invalid) return false; + + if (!is_operand_value(index) || !check_is_assignable_to(c, &index, t_uintptr)) { + gbString e = expr_to_string(index.expr); + gbString t = type_to_string(index.type); + error(index.expr, "'%.*s' expected a uintptr for the memory index, got '%s' of type %s", LIT(builtin_name), e, t); + gb_string_free(t); + gb_string_free(e); + return false; + } + + if (!is_operand_value(delta) || !check_is_assignable_to(c, &delta, t_uintptr)) { + gbString e = expr_to_string(delta.expr); + gbString t = type_to_string(delta.type); + error(delta.expr, "'%.*s' expected a uintptr for the memory delta, got '%s' of type %s", LIT(builtin_name), e, t); + gb_string_free(t); + gb_string_free(e); + return false; + } + + operand->mode = Addressing_Value; + operand->type = t_int; + operand->value = {}; + break; + } + break; + case BuiltinProc_wasm_memory_size: + { + if (!is_arch_wasm()) { + error(call, "'%.*s' is only allowed on wasm targets", LIT(builtin_name)); + return false; + } + + Operand index = {}; + check_expr(c, &index, ce->args[0]); if (index.mode == Addressing_Invalid) return false; + + convert_to_typed(c, &index, t_uintptr); if (index.mode == Addressing_Invalid) return false; + + if (!is_operand_value(index) || !check_is_assignable_to(c, &index, t_uintptr)) { + gbString e = expr_to_string(index.expr); + gbString t = type_to_string(index.type); + error(index.expr, "'%.*s' expected a uintptr for the memory index, got '%s' of type %s", LIT(builtin_name), e, t); + gb_string_free(t); + gb_string_free(e); + return false; + } + + operand->mode = Addressing_Value; + operand->type = t_int; + operand->value = {}; + break; + } + break; + } return true; diff --git a/src/check_decl.cpp b/src/check_decl.cpp index d4a320f03..5acd56097 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -1137,7 +1137,9 @@ 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"); + e->Variable.thread_local_model.len = 0; + // NOTE(bill): ignore this message for the time begin + // error(e->token, "@(thread_local) is not supported for this target platform"); } String context_name = str_lit("variable declaration"); diff --git a/src/checker_builtin_procs.hpp b/src/checker_builtin_procs.hpp index cba952ddf..c647d5a01 100644 --- a/src/checker_builtin_procs.hpp +++ b/src/checker_builtin_procs.hpp @@ -260,6 +260,8 @@ BuiltinProc__type_end, BuiltinProc_constant_utf16_cstring, + BuiltinProc_wasm_memory_grow, + BuiltinProc_wasm_memory_size, BuiltinProc_COUNT, }; @@ -523,4 +525,6 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = { {STR_LIT("constant_utf16_cstring"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("wasm_memory_grow"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("wasm_memory_size"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, }; diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index 2d556b382..d7f3d6c45 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -2207,6 +2207,45 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, return res; } + + case BuiltinProc_wasm_memory_grow: + { + char const *name = "llvm.wasm.memory.grow"; + LLVMTypeRef types[1] = { + lb_type(p->module, t_uintptr), + }; + unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name)); + GB_ASSERT_MSG(id != 0, "Unable to find %s", name, LLVMPrintTypeToString(types[0])); + LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types)); + + LLVMValueRef args[2] = {}; + args[0] = lb_emit_conv(p, lb_build_expr(p, ce->args[0]), t_uintptr).value; + args[1] = lb_emit_conv(p, lb_build_expr(p, ce->args[1]), t_uintptr).value; + + lbValue res = {}; + res.type = tv.type; + res.value = LLVMBuildCall(p->builder, ip, args, gb_count_of(args), ""); + return res; + } + case BuiltinProc_wasm_memory_size: + { + char const *name = "llvm.wasm.memory.size"; + LLVMTypeRef types[1] = { + lb_type(p->module, t_uintptr), + }; + unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name)); + GB_ASSERT_MSG(id != 0, "Unable to find %s", name, LLVMPrintTypeToString(types[0])); + LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types)); + + LLVMValueRef args[1] = {}; + args[0] = lb_emit_conv(p, lb_build_expr(p, ce->args[0]), t_uintptr).value; + + lbValue res = {}; + res.type = tv.type; + res.value = LLVMBuildCall(p->builder, ip, args, gb_count_of(args), ""); + return res; + } + } GB_PANIC("Unhandled built-in procedure %.*s", LIT(builtin_procs[id].name)); -- cgit v1.2.3