mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-05 23:28:48 +00:00
Merge branch 'master' of https://github.com/odin-lang/Odin
This commit is contained in:
@@ -145,7 +145,7 @@ ODIN_OS_STRING :: ODIN_OS_STRING
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
An `enum` value indicating the platform subtarget, chosen using the `-subtarget` switch.
|
An `enum` value indicating the platform subtarget, chosen using the `-subtarget` switch.
|
||||||
Possible values are: `.Default` `.iOS`, .iPhoneSimulator, and `.Android`.
|
Possible values are: `.Default` `.iPhone`, .iPhoneSimulator, and `.Android`.
|
||||||
*/
|
*/
|
||||||
ODIN_PLATFORM_SUBTARGET :: ODIN_PLATFORM_SUBTARGET
|
ODIN_PLATFORM_SUBTARGET :: ODIN_PLATFORM_SUBTARGET
|
||||||
|
|
||||||
|
|||||||
@@ -557,7 +557,7 @@ ALL_ODIN_OS_TYPES :: Odin_OS_Types{
|
|||||||
// Defined internally by the compiler
|
// Defined internally by the compiler
|
||||||
Odin_Platform_Subtarget_Type :: enum int {
|
Odin_Platform_Subtarget_Type :: enum int {
|
||||||
Default,
|
Default,
|
||||||
iOS,
|
iPhone,
|
||||||
iPhoneSimulator
|
iPhoneSimulator
|
||||||
Android,
|
Android,
|
||||||
}
|
}
|
||||||
@@ -566,6 +566,8 @@ Odin_Platform_Subtarget_Type :: type_of(ODIN_PLATFORM_SUBTARGET)
|
|||||||
|
|
||||||
Odin_Platform_Subtarget_Types :: bit_set[Odin_Platform_Subtarget_Type]
|
Odin_Platform_Subtarget_Types :: bit_set[Odin_Platform_Subtarget_Type]
|
||||||
|
|
||||||
|
@(builtin)
|
||||||
|
ODIN_PLATFORM_SUBTARGET_IOS :: ODIN_PLATFORM_SUBTARGET == .iPhone || ODIN_PLATFORM_SUBTARGET == .iPhoneSimulator
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// Defined internally by the compiler
|
// Defined internally by the compiler
|
||||||
|
|||||||
@@ -21,8 +21,7 @@ hash_string :: proc(algorithm: Algorithm, data: string, allocator := context.all
|
|||||||
// in a newly allocated slice.
|
// in a newly allocated slice.
|
||||||
hash_bytes :: proc(algorithm: Algorithm, data: []byte, allocator := context.allocator) -> []byte {
|
hash_bytes :: proc(algorithm: Algorithm, data: []byte, allocator := context.allocator) -> []byte {
|
||||||
dst := make([]byte, DIGEST_SIZES[algorithm], allocator)
|
dst := make([]byte, DIGEST_SIZES[algorithm], allocator)
|
||||||
hash_bytes_to_buffer(algorithm, data, dst)
|
return hash_bytes_to_buffer(algorithm, data, dst)
|
||||||
return dst
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// hash_string_to_buffer will hash the given input and assign the
|
// hash_string_to_buffer will hash the given input and assign the
|
||||||
@@ -46,7 +45,7 @@ hash_bytes_to_buffer :: proc(algorithm: Algorithm, data, hash: []byte) -> []byte
|
|||||||
update(&ctx, data)
|
update(&ctx, data)
|
||||||
final(&ctx, hash)
|
final(&ctx, hash)
|
||||||
|
|
||||||
return hash
|
return hash[:DIGEST_SIZES[algorithm]]
|
||||||
}
|
}
|
||||||
|
|
||||||
// hash_stream will incrementally fully consume a stream, and return the
|
// hash_stream will incrementally fully consume a stream, and return the
|
||||||
|
|||||||
@@ -967,8 +967,8 @@ _processor_core_count :: proc() -> int {
|
|||||||
@(private, require_results)
|
@(private, require_results)
|
||||||
_alloc_command_line_arguments :: proc() -> []string {
|
_alloc_command_line_arguments :: proc() -> []string {
|
||||||
res := make([]string, len(runtime.args__))
|
res := make([]string, len(runtime.args__))
|
||||||
for arg, i in runtime.args__ {
|
for _, i in res {
|
||||||
res[i] = string(arg)
|
res[i] = string(runtime.args__[i])
|
||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1100,8 +1100,8 @@ _processor_core_count :: proc() -> int {
|
|||||||
@(private, require_results)
|
@(private, require_results)
|
||||||
_alloc_command_line_arguments :: proc() -> []string {
|
_alloc_command_line_arguments :: proc() -> []string {
|
||||||
res := make([]string, len(runtime.args__))
|
res := make([]string, len(runtime.args__))
|
||||||
for arg, i in runtime.args__ {
|
for _, i in res {
|
||||||
res[i] = string(arg)
|
res[i] = string(runtime.args__[i])
|
||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1017,8 +1017,8 @@ _processor_core_count :: proc() -> int {
|
|||||||
@(private, require_results)
|
@(private, require_results)
|
||||||
_alloc_command_line_arguments :: proc() -> []string {
|
_alloc_command_line_arguments :: proc() -> []string {
|
||||||
res := make([]string, len(runtime.args__))
|
res := make([]string, len(runtime.args__))
|
||||||
for arg, i in runtime.args__ {
|
for _, i in res {
|
||||||
res[i] = string(arg)
|
res[i] = string(runtime.args__[i])
|
||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -917,8 +917,8 @@ _processor_core_count :: proc() -> int {
|
|||||||
@(private, require_results)
|
@(private, require_results)
|
||||||
_alloc_command_line_arguments :: proc() -> []string {
|
_alloc_command_line_arguments :: proc() -> []string {
|
||||||
res := make([]string, len(runtime.args__))
|
res := make([]string, len(runtime.args__))
|
||||||
for arg, i in runtime.args__ {
|
for _, i in res {
|
||||||
res[i] = string(arg)
|
res[i] = string(runtime.args__[i])
|
||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#+build !wasi
|
#+build !wasi
|
||||||
|
#+build !js
|
||||||
package filepath
|
package filepath
|
||||||
|
|
||||||
import "core:os"
|
import "core:os"
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#+build !wasi
|
#+build !wasi
|
||||||
|
#+build !js
|
||||||
package filepath
|
package filepath
|
||||||
|
|
||||||
import "core:os"
|
import "core:os"
|
||||||
|
|||||||
@@ -3,23 +3,13 @@ package darwin
|
|||||||
// #define OS_WAIT_ON_ADDR_AVAILABILITY \
|
// #define OS_WAIT_ON_ADDR_AVAILABILITY \
|
||||||
// __API_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
|
// __API_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
|
||||||
when ODIN_OS == .Darwin {
|
when ODIN_OS == .Darwin {
|
||||||
|
when ODIN_PLATFORM_SUBTARGET_IOS {
|
||||||
when ODIN_PLATFORM_SUBTARGET == .iOS && ODIN_MINIMUM_OS_VERSION >= 17_04_00 {
|
WAIT_ON_ADDRESS_AVAILABLE :: ODIN_MINIMUM_OS_VERSION >= 17_04_00
|
||||||
WAIT_ON_ADDRESS_AVAILABLE :: true
|
ULOCK_WAIT_2_AVAILABLE :: ODIN_MINIMUM_OS_VERSION >= 14_00_00
|
||||||
} else when ODIN_MINIMUM_OS_VERSION >= 14_04_00 {
|
|
||||||
WAIT_ON_ADDRESS_AVAILABLE :: true
|
|
||||||
} else {
|
} else {
|
||||||
WAIT_ON_ADDRESS_AVAILABLE :: false
|
WAIT_ON_ADDRESS_AVAILABLE :: ODIN_MINIMUM_OS_VERSION >= 14_04_00
|
||||||
|
ULOCK_WAIT_2_AVAILABLE :: ODIN_MINIMUM_OS_VERSION >= 11_00_00
|
||||||
}
|
}
|
||||||
|
|
||||||
when ODIN_PLATFORM_SUBTARGET == .iOS && ODIN_MINIMUM_OS_VERSION >= 14_00_00 {
|
|
||||||
ULOCK_WAIT_2_AVAILABLE :: true
|
|
||||||
} else when ODIN_MINIMUM_OS_VERSION >= 11_00_00 {
|
|
||||||
ULOCK_WAIT_2_AVAILABLE :: true
|
|
||||||
} else {
|
|
||||||
ULOCK_WAIT_2_AVAILABLE :: false
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
WAIT_ON_ADDRESS_AVAILABLE :: false
|
WAIT_ON_ADDRESS_AVAILABLE :: false
|
||||||
ULOCK_WAIT_2_AVAILABLE :: false
|
ULOCK_WAIT_2_AVAILABLE :: false
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ init_platform :: proc() {
|
|||||||
|
|
||||||
macos_version = {int(version.majorVersion), int(version.minorVersion), int(version.patchVersion)}
|
macos_version = {int(version.majorVersion), int(version.minorVersion), int(version.patchVersion)}
|
||||||
|
|
||||||
when ODIN_PLATFORM_SUBTARGET == .iOS {
|
when ODIN_PLATFORM_SUBTARGET_IOS {
|
||||||
os_version.platform = .iOS
|
os_version.platform = .iOS
|
||||||
ws(&b, "iOS")
|
ws(&b, "iOS")
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -25,11 +25,12 @@ COINIT :: enum DWORD {
|
|||||||
SPEED_OVER_MEMORY = 0x8,
|
SPEED_OVER_MEMORY = 0x8,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IUnknown_UUID_STRING :: "00000000-0000-0000-C000-000000000046"
|
||||||
|
IUnknown_UUID := &IID{0x00000000, 0x0000, 0x0000, {0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}}
|
||||||
|
IUnknownVtbl :: IUnknown_VTable
|
||||||
IUnknown :: struct {
|
IUnknown :: struct {
|
||||||
using _iunknown_vtable: ^IUnknown_VTable,
|
using _iunknown_vtable: ^IUnknown_VTable,
|
||||||
}
|
}
|
||||||
|
|
||||||
IUnknownVtbl :: IUnknown_VTable
|
|
||||||
IUnknown_VTable :: struct {
|
IUnknown_VTable :: struct {
|
||||||
QueryInterface: proc "system" (This: ^IUnknown, riid: REFIID, ppvObject: ^rawptr) -> HRESULT,
|
QueryInterface: proc "system" (This: ^IUnknown, riid: REFIID, ppvObject: ^rawptr) -> HRESULT,
|
||||||
AddRef: proc "system" (This: ^IUnknown) -> ULONG,
|
AddRef: proc "system" (This: ^IUnknown) -> ULONG,
|
||||||
|
|||||||
@@ -171,7 +171,7 @@ struct TargetMetrics {
|
|||||||
|
|
||||||
enum Subtarget : u32 {
|
enum Subtarget : u32 {
|
||||||
Subtarget_Default,
|
Subtarget_Default,
|
||||||
Subtarget_iOS,
|
Subtarget_iPhone,
|
||||||
Subtarget_iPhoneSimulator,
|
Subtarget_iPhoneSimulator,
|
||||||
Subtarget_Android,
|
Subtarget_Android,
|
||||||
|
|
||||||
@@ -180,7 +180,7 @@ enum Subtarget : u32 {
|
|||||||
|
|
||||||
gb_global String subtarget_strings[Subtarget_COUNT] = {
|
gb_global String subtarget_strings[Subtarget_COUNT] = {
|
||||||
str_lit(""),
|
str_lit(""),
|
||||||
str_lit("ios"),
|
str_lit("iphone"),
|
||||||
str_lit("iphonesimulator"),
|
str_lit("iphonesimulator"),
|
||||||
str_lit("android"),
|
str_lit("android"),
|
||||||
};
|
};
|
||||||
@@ -1828,13 +1828,13 @@ gb_internal void init_build_context(TargetMetrics *cross_target, Subtarget subta
|
|||||||
|
|
||||||
if (metrics->os == TargetOs_darwin) {
|
if (metrics->os == TargetOs_darwin) {
|
||||||
switch (subtarget) {
|
switch (subtarget) {
|
||||||
case Subtarget_iOS:
|
case Subtarget_iPhone:
|
||||||
switch (metrics->arch) {
|
switch (metrics->arch) {
|
||||||
case TargetArch_arm64:
|
case TargetArch_arm64:
|
||||||
bc->metrics.target_triplet = str_lit("arm64-apple-ios");
|
bc->metrics.target_triplet = str_lit("arm64-apple-ios");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
GB_PANIC("Unknown architecture for -subtarget:ios");
|
GB_PANIC("Unknown architecture for -subtarget:iphone");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Subtarget_iPhoneSimulator:
|
case Subtarget_iPhoneSimulator:
|
||||||
@@ -1909,7 +1909,7 @@ gb_internal void init_build_context(TargetMetrics *cross_target, Subtarget subta
|
|||||||
if (!bc->minimum_os_version_string_given) {
|
if (!bc->minimum_os_version_string_given) {
|
||||||
if (subtarget == Subtarget_Default) {
|
if (subtarget == Subtarget_Default) {
|
||||||
bc->minimum_os_version_string = str_lit("11.0.0");
|
bc->minimum_os_version_string = str_lit("11.0.0");
|
||||||
} else if (subtarget == Subtarget_iOS || subtarget == Subtarget_iPhoneSimulator) {
|
} else if (subtarget == Subtarget_iPhone || subtarget == Subtarget_iPhoneSimulator) {
|
||||||
// NOTE(harold): We default to 17.4 on iOS because that's when os_sync_wait_on_address was added and
|
// NOTE(harold): We default to 17.4 on iOS because that's when os_sync_wait_on_address was added and
|
||||||
// we'd like to avoid any potential App Store issues by using the private ulock_* there.
|
// we'd like to avoid any potential App Store issues by using the private ulock_* there.
|
||||||
bc->minimum_os_version_string = str_lit("17.4");
|
bc->minimum_os_version_string = str_lit("17.4");
|
||||||
@@ -1917,7 +1917,7 @@ gb_internal void init_build_context(TargetMetrics *cross_target, Subtarget subta
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (subtarget == Subtarget_iPhoneSimulator) {
|
if (subtarget == Subtarget_iPhoneSimulator) {
|
||||||
// For the iOS simulator subtarget, the version must be between 'ios' and '-simulator'.
|
// For the iPhoneSimulator subtarget, the version must be between 'ios' and '-simulator'.
|
||||||
String suffix = str_lit("-simulator");
|
String suffix = str_lit("-simulator");
|
||||||
GB_ASSERT(string_ends_with(bc->metrics.target_triplet, suffix));
|
GB_ASSERT(string_ends_with(bc->metrics.target_triplet, suffix));
|
||||||
|
|
||||||
|
|||||||
+107
-99
@@ -1001,119 +1001,127 @@ gb_internal String handle_link_name(CheckerContext *ctx, Token token, String lin
|
|||||||
|
|
||||||
|
|
||||||
gb_internal void check_objc_methods(CheckerContext *ctx, Entity *e, AttributeContext &ac) {
|
gb_internal void check_objc_methods(CheckerContext *ctx, Entity *e, AttributeContext &ac) {
|
||||||
if (!(ac.objc_name.len || ac.objc_is_class_method || ac.objc_type)) {
|
if (!ac.objc_type) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
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) {
|
|
||||||
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;
|
|
||||||
|
|
||||||
GB_ASSERT(t->kind == Type_Named); // NOTE(harold): This is already checked for at the attribute resolution stage.
|
Type *t = ac.objc_type;
|
||||||
Entity *tn = t->Named.type_name;
|
GB_ASSERT(t->kind == Type_Named); // NOTE(harold): This is already checked for at the attribute resolution stage.
|
||||||
|
|
||||||
GB_ASSERT(tn->kind == Entity_TypeName);
|
// Attempt to infer th objc_name automatically if the proc name contains
|
||||||
|
// the type name objc_type's name, followed by an underscore, as a prefix.
|
||||||
|
if (ac.objc_name.len == 0) {
|
||||||
|
String proc_name = e->token.string;
|
||||||
|
String type_name = t->Named.name;
|
||||||
|
|
||||||
if (tn->scope != e->scope) {
|
if (proc_name.len > type_name.len + 1 &&
|
||||||
error(e->token, "@(objc_name) attribute may only be applied to procedures and types within the same scope");
|
proc_name[type_name.len] == '_' &&
|
||||||
|
str_eq(type_name, substring(proc_name, 0, type_name.len))
|
||||||
|
) {
|
||||||
|
ac.objc_name = substring(proc_name, type_name.len+1, proc_name.len);
|
||||||
} else {
|
} else {
|
||||||
|
error(e->token, "@(objc_name) requires that @(objc_type) be set or inferred "
|
||||||
|
"by prefixing the proc name with the type and underscore: MyObjcType_myProcName :: proc().");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Enable implementation by default if the class is an implementer too and
|
Entity *tn = t->Named.type_name;
|
||||||
// @objc_implement was not set to false explicitly in this proc.
|
GB_ASSERT(tn->kind == Entity_TypeName);
|
||||||
bool implement = tn->TypeName.objc_is_implementation;
|
|
||||||
if (ac.objc_is_disabled_implement) {
|
|
||||||
implement = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (implement) {
|
if (tn->scope != e->scope) {
|
||||||
GB_ASSERT(e->kind == Entity_Procedure);
|
error(e->token, "@(objc_name) attribute may only be applied to procedures and types within the same scope");
|
||||||
|
} else {
|
||||||
|
// Enable implementation by default if the class is an implementer too and
|
||||||
|
// @objc_implement was not set to false explicitly in this proc.
|
||||||
|
bool implement = tn->TypeName.objc_is_implementation;
|
||||||
|
if (ac.objc_is_disabled_implement) {
|
||||||
|
implement = false;
|
||||||
|
}
|
||||||
|
|
||||||
auto &proc = e->type->Proc;
|
if (implement) {
|
||||||
Type *first_param = proc.param_count > 0 ? proc.params->Tuple.variables[0]->type : t_untyped_nil;
|
GB_ASSERT(e->kind == Entity_Procedure);
|
||||||
|
|
||||||
if (!tn->TypeName.objc_is_implementation) {
|
auto &proc = e->type->Proc;
|
||||||
error(e->token, "@(objc_is_implement) attribute may only be applied to procedures whose class also have @(objc_is_implement) applied");
|
Type *first_param = proc.param_count > 0 ? proc.params->Tuple.variables[0]->type : t_untyped_nil;
|
||||||
} else if (!ac.objc_is_class_method && !(first_param->kind == Type_Pointer && internal_check_is_assignable_to(t, first_param->Pointer.elem))) {
|
|
||||||
error(e->token, "Objective-C instance methods implementations require the first parameter to be a pointer to the class type set by @(objc_type)");
|
|
||||||
} else if (proc.calling_convention == ProcCC_Odin && !tn->TypeName.objc_context_provider) {
|
|
||||||
error(e->token, "Objective-C methods with Odin calling convention can only be used with classes that have @(objc_context_provider) set");
|
|
||||||
} else if (ac.objc_is_class_method && proc.calling_convention != ProcCC_CDecl) {
|
|
||||||
error(e->token, "Objective-C class methods (objc_is_class_method=true) that have @objc_is_implementation can only use \"c\" calling convention");
|
|
||||||
} else if (proc.result_count > 1) {
|
|
||||||
error(e->token, "Objective-C method implementations may return at most 1 value");
|
|
||||||
} else {
|
|
||||||
// Always export unconditionally
|
|
||||||
// NOTE(harold): This means check_objc_methods() MUST be called before
|
|
||||||
// e->Procedure.is_export is set in check_proc_decl()!
|
|
||||||
if (ac.is_export) {
|
|
||||||
error(e->token, "Explicit export not allowed when @(objc_implement) is set. It set exported implicitly");
|
|
||||||
}
|
|
||||||
if (ac.link_name != "") {
|
|
||||||
error(e->token, "Explicit linkage not allowed when @(objc_implement) is set. It set to \"strong\" implicitly");
|
|
||||||
}
|
|
||||||
|
|
||||||
ac.is_export = true;
|
if (!tn->TypeName.objc_is_implementation) {
|
||||||
ac.linkage = STR_LIT("strong");
|
error(e->token, "@(objc_is_implement) attribute may only be applied to procedures whose class also have @(objc_is_implement) applied");
|
||||||
|
} else if (!ac.objc_is_class_method && !(first_param->kind == Type_Pointer && internal_check_is_assignable_to(t, first_param->Pointer.elem))) {
|
||||||
auto method = ObjcMethodData{ ac, e };
|
error(e->token, "Objective-C instance methods implementations require the first parameter to be a pointer to the class type set by @(objc_type)");
|
||||||
method.ac.objc_selector = ac.objc_selector != "" ? ac.objc_selector : ac.objc_name;
|
} else if (proc.calling_convention == ProcCC_Odin && !tn->TypeName.objc_context_provider) {
|
||||||
|
error(e->token, "Objective-C methods with Odin calling convention can only be used with classes that have @(objc_context_provider) set");
|
||||||
CheckerInfo *info = ctx->info;
|
} else if (ac.objc_is_class_method && proc.calling_convention != ProcCC_CDecl) {
|
||||||
mutex_lock(&info->objc_method_mutex);
|
error(e->token, "Objective-C class methods (objc_is_class_method=true) that have @objc_is_implementation can only use \"c\" calling convention");
|
||||||
defer (mutex_unlock(&info->objc_method_mutex));
|
} else if (proc.result_count > 1) {
|
||||||
|
error(e->token, "Objective-C method implementations may return at most 1 value");
|
||||||
Array<ObjcMethodData>* method_list = map_get(&info->objc_method_implementations, t);
|
|
||||||
if (method_list) {
|
|
||||||
array_add(method_list, method);
|
|
||||||
} else {
|
|
||||||
auto list = array_make<ObjcMethodData>(permanent_allocator(), 1, 8);
|
|
||||||
list[0] = method;
|
|
||||||
|
|
||||||
map_set(&info->objc_method_implementations, t, list);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (ac.objc_selector != "") {
|
|
||||||
error(e->token, "@(objc_selector) may only be applied to procedures that are Objective-C implementations.");
|
|
||||||
}
|
|
||||||
|
|
||||||
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_is_class_method) {
|
|
||||||
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 {
|
} else {
|
||||||
bool ok = true;
|
// Always export unconditionally
|
||||||
for (TypeNameObjCMetadataEntry const &entry : md->type_entries) {
|
// NOTE(harold): This means check_objc_methods() MUST be called before
|
||||||
if (entry.name == ac.objc_name) {
|
// e->Procedure.is_export is set in check_proc_decl()!
|
||||||
error(e->token, "Previous declaration of @(objc_name=\"%.*s\")", LIT(ac.objc_name));
|
if (ac.is_export) {
|
||||||
ok = false;
|
error(e->token, "Explicit export not allowed when @(objc_implement) is set. It set exported implicitly");
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (ok) {
|
if (ac.link_name != "") {
|
||||||
array_add(&md->type_entries, TypeNameObjCMetadataEntry{ac.objc_name, e});
|
error(e->token, "Explicit linkage not allowed when @(objc_implement) is set. It set to \"strong\" implicitly");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ac.is_export = true;
|
||||||
|
ac.linkage = STR_LIT("strong");
|
||||||
|
|
||||||
|
auto method = ObjcMethodData{ ac, e };
|
||||||
|
method.ac.objc_selector = ac.objc_selector != "" ? ac.objc_selector : ac.objc_name;
|
||||||
|
|
||||||
|
CheckerInfo *info = ctx->info;
|
||||||
|
mutex_lock(&info->objc_method_mutex);
|
||||||
|
defer (mutex_unlock(&info->objc_method_mutex));
|
||||||
|
|
||||||
|
Array<ObjcMethodData>* method_list = map_get(&info->objc_method_implementations, t);
|
||||||
|
if (method_list) {
|
||||||
|
array_add(method_list, method);
|
||||||
|
} else {
|
||||||
|
auto list = array_make<ObjcMethodData>(permanent_allocator(), 1, 8);
|
||||||
|
list[0] = method;
|
||||||
|
|
||||||
|
map_set(&info->objc_method_implementations, t, list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (ac.objc_selector != "") {
|
||||||
|
error(e->token, "@(objc_selector) may only be applied to procedures that are Objective-C implementations.");
|
||||||
|
}
|
||||||
|
|
||||||
|
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_is_class_method) {
|
||||||
|
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_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_name, e});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -1172,7 +1172,7 @@ gb_internal void init_universal(void) {
|
|||||||
{
|
{
|
||||||
GlobalEnumValue values[Subtarget_COUNT] = {
|
GlobalEnumValue values[Subtarget_COUNT] = {
|
||||||
{"Default", Subtarget_Default},
|
{"Default", Subtarget_Default},
|
||||||
{"iOS", Subtarget_iOS},
|
{"iPhone", Subtarget_iPhone},
|
||||||
{"iPhoneSimulator", Subtarget_iPhoneSimulator},
|
{"iPhoneSimulator", Subtarget_iPhoneSimulator},
|
||||||
{"Android", Subtarget_Android},
|
{"Android", Subtarget_Android},
|
||||||
};
|
};
|
||||||
|
|||||||
+1
-1
@@ -787,7 +787,7 @@ try_cross_linking:;
|
|||||||
// being set to 'MacOSX' even though we've set the sysroot to the correct SDK (-Wincompatible-sysroot).
|
// being set to 'MacOSX' even though we've set the sysroot to the correct SDK (-Wincompatible-sysroot).
|
||||||
// This is because it is likely not using the SDK's toolchain Apple Clang but another one installed in the system.
|
// This is because it is likely not using the SDK's toolchain Apple Clang but another one installed in the system.
|
||||||
switch (selected_subtarget) {
|
switch (selected_subtarget) {
|
||||||
case Subtarget_iOS:
|
case Subtarget_iPhone:
|
||||||
darwin_platform_name = "iPhoneOS";
|
darwin_platform_name = "iPhoneOS";
|
||||||
darwin_xcrun_sdk_name = "iphoneos";
|
darwin_xcrun_sdk_name = "iphoneos";
|
||||||
darwin_min_version_id = "ios";
|
darwin_min_version_id = "ios";
|
||||||
|
|||||||
Vendored
+6
-6
@@ -89,12 +89,12 @@ foreign lib {
|
|||||||
ReadXPMFromArrayToRGB888 :: proc(xpm: [^]cstring) -> ^SDL.Surface ---
|
ReadXPMFromArrayToRGB888 :: proc(xpm: [^]cstring) -> ^SDL.Surface ---
|
||||||
|
|
||||||
/* Individual saving functions */
|
/* Individual saving functions */
|
||||||
SaveAVIF :: proc(surface: ^SDL.Surface, file: cstring, quality: c.int) -> c.int ---
|
SaveAVIF :: proc(surface: ^SDL.Surface, file: cstring, quality: c.int) -> c.bool ---
|
||||||
SaveAVIF_IO :: proc(surface: ^SDL.Surface, dst: ^SDL.IOStream, closeio: bool, quality: c.int) -> c.int ---
|
SaveAVIF_IO :: proc(surface: ^SDL.Surface, dst: ^SDL.IOStream, closeio: bool, quality: c.int) -> c.bool ---
|
||||||
SavePNG :: proc(surface: ^SDL.Surface, file: cstring) -> c.int ---
|
SavePNG :: proc(surface: ^SDL.Surface, file: cstring) -> c.bool ---
|
||||||
SavePNG_IO :: proc(surface: ^SDL.Surface, dst: ^SDL.IOStream, closeio: bool) -> c.int ---
|
SavePNG_IO :: proc(surface: ^SDL.Surface, dst: ^SDL.IOStream, closeio: bool) -> c.bool ---
|
||||||
SaveJPG :: proc(surface: ^SDL.Surface, file: cstring, quality: c.int) -> c.int ---
|
SaveJPG :: proc(surface: ^SDL.Surface, file: cstring, quality: c.int) -> c.bool ---
|
||||||
SaveJPG_IO :: proc(surface: ^SDL.Surface, dst: ^SDL.IOStream, closeio: bool, quality: c.int) -> c.int ---
|
SaveJPG_IO :: proc(surface: ^SDL.Surface, dst: ^SDL.IOStream, closeio: bool, quality: c.int) -> c.bool ---
|
||||||
|
|
||||||
LoadAnimation :: proc(file: cstring) -> ^Animation ---
|
LoadAnimation :: proc(file: cstring) -> ^Animation ---
|
||||||
LoadAnimation_IO :: proc(src: ^SDL.IOStream, closeio: bool) -> ^Animation ---
|
LoadAnimation_IO :: proc(src: ^SDL.IOStream, closeio: bool) -> ^Animation ---
|
||||||
|
|||||||
Reference in New Issue
Block a user