Vendor things

This commit is contained in:
John Doty 2024-03-08 11:03:01 -08:00
parent 5deceec006
commit 977e3c17e5
19434 changed files with 10682014 additions and 0 deletions

View file

@ -0,0 +1 @@
{"files":{"CHANGELOG.md":"12251c636fde739442826aedf8fa5dfbf66dd7621b7f960bc96ee49a10578fe1","Cargo.toml":"757fc50efb3cb9c82a4d06295b13bec171369044d98a896d36cabbc1a215d561","README.md":"90a788330c35086f58f3e5a2e16c3f1a346677a8ea581c9dd732b18202c09617","build.rs":"a37fc2c8fbfe7c3ccbefe69e87158b0ce9c4a9a854c253f3151d4fc960cd6c17","compat-headers-objfw/objc/objc.h":"4f0bd9357cae1ecb18280074385a13b355cce77bb0705ea3b77b51ec0adbd0d5","compat-headers-objfw/objc/runtime.h":"4f0bd9357cae1ecb18280074385a13b355cce77bb0705ea3b77b51ec0adbd0d5","extern/exception.m":"6c7431237864f010a069f6d6b026d1dab089bcf5fda8cec4ec2a67c3c70ec72f","src/class.rs":"e11129d713055cd46424d38bd4badd9b15d380da3d65e691e4db2858c08f44d8","src/constants.rs":"27595c1d93919ec9feb770fab0abd6d912fb60799b804fe4b2dfa04227020b92","src/exception.rs":"6230603802731a04ab9b2aebeddc2c436e479d7e725731dcb4ff15736a4952cc","src/image_info.rs":"b42710f6e3d12dd0f6446fa92c84c060618e9e6cdbc4d790ac824d6100e4be07","src/lib.rs":"a4b2ad2510ca6d4eb6c101d211147206bc567a2a52bb3bb4d391249fa0c3d8f3","src/message.rs":"3db369688d476027803fa83012cd0228443672bb78f4888da09eca875ad2183b","src/method.rs":"fb1b47c43b04fd65279e61e0aea9fb56898614574351f4a79785e3cec98229f6","src/object.rs":"defa71757c5cd646e676643349c0dbe86e9a4ea86aa8385bce43b47d192a891e","src/property.rs":"aa0e2e75878cf869bae290a0a200b4d9d859147588a8c3a1d83e95837257e138","src/protocol.rs":"3dc526288ba0933f799160873722ca425cbf0236d819af4fd43fe5f1b65b1abb","src/rc.rs":"f13b3cae6065748ecc889d293d22b5f0efeaa8b0b2188ebe4b0319e69651270e","src/selector.rs":"15d4afaf1d876e085090eb40b168deef8665ce35cc5b0e194f403131a17ef98e","src/types.rs":"f5111c3d79e1bbf58a8a128c1e5a6d1bc42164b226a37328e65585dbe620b12e","src/various.rs":"78f6c455af3d7cea86f0239404b035e4831d9b415bdb468ded26501501a39617"},"package":"df3b9834c1e95694a05a828b59f55fa2afec6288359cda67146126b3f90a55d7"}

100
third-party/vendor/objc-sys/CHANGELOG.md vendored Normal file
View file

@ -0,0 +1,100 @@
# Changelog
Notable changes to this crate will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## Unreleased - YYYY-MM-DD
## 0.2.0-beta.2 - 2022-08-28
### Fixed
* Fixed `docs.rs` setup.
## 0.2.0-beta.1 - 2022-07-19
### Added
* Added `unstable-c-unwind` feature.
* Use `doc_auto_cfg` to improve documentation output.
## 0.2.0-beta.0 - 2022-06-13
### Changed
* **BREAKING**: Changed `links` key from `objc` to `objc_0_2` for better
future compatibility, until we reach 1.0 (so `DEP_OBJC_CC_ARGS` in build
scripts becomes `DEP_OBJC_0_2_CC_ARGS`).
* **BREAKING**: Apple's runtime is now always the default.
### Removed
* **BREAKING**: Removed type aliases `Class`, `Ivar`, `Method` and `Protocol`
since they could easily be mistaken for the `objc2::runtime` structs with
the same name.
* **BREAKING**: Removed `objc_property_t`.
* **BREAKING**: Removed `objc_hook_getClass` and `objc_hook_lazyClassNamer`
type aliases (for now).
* **BREAKING**: Removed `DEP_OBJC_RUNTIME` build script output.
## 0.2.0-alpha.1 - 2022-01-03
### Added
* Added `objc_exception_try_enter` and `objc_exception_try_exit` on macOS x86.
### Changed
* **BREAKING**: Correctly `cfg`-guarded the following types and methods to not
be available on macOS x86:
- `objc_exception_matcher`
- `objc_exception_preprocessor`
- `objc_uncaught_exception_handler`
- `objc_exception_handler`
- `objc_begin_catch`
- `objc_end_catch`
- `objc_exception_rethrow`
- `objc_setExceptionMatcher`
- `objc_setExceptionPreprocessor`
- `objc_setUncaughtExceptionHandler`
- `objc_addExceptionHandler`
- `objc_removeExceptionHandler`
### Removed
* **BREAKING**: Removed`objc_set_apple_compatible_objcxx_exceptions` since it
is only available when `libobjc2` is compiled with the correct flags.
* **BREAKING**: Removed `object_setInstanceVariableWithStrongDefault` since it
is only available since macOS 10.12.
* **BREAKING**: Removed `objc_setHook_getClass` since it is only available
since macOS 10.14.4.
* **BREAKING**: Removed `objc_setHook_lazyClassNamer` since it is only
available since macOS 11.
## Fixed
* `docs.rs` configuration.
## 0.2.0-alpha.0 - 2021-12-22
## Added
* `NSInteger` and `NSUInteger` (type aliases of `isize`/`usize`).
* `NSIntegerMax`, `NSIntegerMin` and `NSUIntegerMax`.
### Changed
* **BREAKING**: `cfg`-guarded `class_getImageName` to only appear on Apple
platforms.
### Fixed
* **BREAKING**: Opaque types are now also `!UnwindSafe`.
## 0.1.0 - 2021-11-22
### Changed
* **BREAKING**: Use feature flags `apple`, `gnustep-X-Y` or `winobjc` to
specify the runtime you're using, instead of the `RUNTIME_VERSION`
environment variable.
* **BREAKING**: `DEP_OBJC_RUNTIME` now returns `gnustep` on WinObjC.
## 0.0.1 - 2021-10-28
Initial release.

75
third-party/vendor/objc-sys/Cargo.toml vendored Normal file
View file

@ -0,0 +1,75 @@
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
#
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
# to registry (e.g., crates.io) dependencies.
#
# If you are reading this file be aware that the original Cargo.toml
# will likely look very different (and much more reasonable).
# See Cargo.toml.orig for the original contents.
[package]
edition = "2021"
name = "objc-sys"
version = "0.2.0-beta.2"
authors = ["Mads Marquart <mads@marquart.dk>"]
build = "build.rs"
links = "objc_0_2"
description = "Raw bindings to the Objective-C runtime and ABI"
documentation = "https://docs.rs/objc-sys/"
readme = "README.md"
keywords = [
"objective-c",
"macos",
"ios",
"objc_msgSend",
"sys",
]
categories = [
"external-ffi-bindings",
"os::macos-apis",
]
license = "MIT"
repository = "https://github.com/madsmtm/objc2"
resolver = "2"
[package.metadata.docs.rs]
default-target = "x86_64-apple-darwin"
no-default-features = true
features = [
"std",
"unstable-docsrs",
]
targets = [
"x86_64-apple-darwin",
"aarch64-apple-darwin",
"aarch64-apple-ios",
"x86_64-apple-ios",
"x86_64-unknown-linux-gnu",
"i686-unknown-linux-gnu",
"x86_64-pc-windows-msvc",
]
[build-dependencies.cc]
version = "1"
optional = true
[features]
alloc = []
apple = []
default = [
"std",
"apple",
]
gnustep-1-7 = []
gnustep-1-8 = ["gnustep-1-7"]
gnustep-1-9 = ["gnustep-1-8"]
gnustep-2-0 = ["gnustep-1-9"]
gnustep-2-1 = ["gnustep-2-0"]
std = ["alloc"]
unstable-c-unwind = []
unstable-docsrs = []
unstable-exception = ["cc"]
unstable-objfw = []
unstable-winobjc = ["gnustep-1-8"]

161
third-party/vendor/objc-sys/README.md vendored Normal file
View file

@ -0,0 +1,161 @@
# `objc-sys`
[![Latest version](https://badgen.net/crates/v/objc-sys)](https://crates.io/crates/objc-sys)
[![License](https://badgen.net/badge/license/MIT/blue)](../LICENSE.txt)
[![Documentation](https://docs.rs/objc-sys/badge.svg)](https://docs.rs/objc-sys/)
[![CI](https://github.com/madsmtm/objc2/actions/workflows/ci.yml/badge.svg)](https://github.com/madsmtm/objc2/actions/workflows/ci.yml)
Raw Rust bindings to the Objective-C runtime and ABI.
This crate is part of the [`objc2` project](https://github.com/madsmtm/objc2),
see that for related crates.
## Runtime Support
Objective-C has a runtime, different implementations of said runtime exist,
and they act in slightly different ways. By default, Apple platforms link to
Apple's runtime, but if you're using another runtime you must tell it to this
library using feature flags (you might have to disable the default `apple`
feature first).
One could ask, why even bother supporting other runtimes? To that, there's a
simple answer: _Robustness_. By testing with these alternative runtimes in CI,
we become by extension much more confident that our implementation doesn't
rely on brittle unspecified behaviour, and works across different macOS and
iOS versions.
### Apple's [`objc4`](https://github.com/apple-oss-distributions/objc4)
- Feature flag: `apple`.
This is used by default.
The supported runtime version (higher versions lets the compiler enable newer
optimizations, at the cost of not supporting older operating systems) can be
chosen using the standard `X_DEPLOYMENT_TARGET` environment variables:
- macOS: `MACOSX_DEPLOYMENT_TARGET`
- Default: `10.7` ([same as Rust](https://github.com/rust-lang/rust/blob/1.56.0/compiler/rustc_target/src/spec/apple_base.rs#L67))
- Minimum: `10.7`
- iOS: `IPHONEOS_DEPLOYMENT_TARGET`
- Default: `7.0` ([same as Rust](https://github.com/rust-lang/rust/blob/1.56.0/compiler/rustc_target/src/spec/apple_base.rs#L92))
- Minimum: `5.0` (theoretically)
- tvOS: `TVOS_DEPLOYMENT_TARGET`
- Default: TODO
- Minimum: `9.0` (theoretically)
- watchOS: `WATCHOS_DEPLOYMENT_TARGET`
- Default: TODO
- Minimum: `1.0` (theoretically)
### GNUStep's [`libobjc2`](https://github.com/gnustep/libobjc2)
- Feature flag: `gnustep-1-7`, `gnustep-1-8`, `gnustep-1-9`, `gnustep-2-0` and
`gnustep-2-1` depending on the version you're using. Recommended default is
`gnustep-1-8`.
### Microsoft's [`WinObjC`](https://github.com/microsoft/WinObjC)
- Feature flag: `unstable-winobjc`.
**Unstable: Hasn't been tested on Windows yet!**
This is essentially just [a fork](https://github.com/microsoft/libobjc2) based
on GNUStep's `libobjc2` version 1.8, with very few user-facing changes.
### [`ObjFW`](https://github.com/ObjFW/ObjFW)
- Feature flag: `unstable-objfw`.
**Unstable: Doesn't work yet!**
TODO.
### Other runtimes
This library will probably only ever support ["Modern"][modern] Objective-C
runtimes, since support for reference-counting primitives like `objc_retain`
and `objc_autoreleasePoolPop` is a vital requirement for most applications.
Just so we're being clear, this rules out the GCC [`libobjc`][gcc-libobjc]
runtime (see [this][gcc-objc-support]), the [`mulle-objc`] runtime and
[cocotron]. (But support for [`darling`] may be added).
More information on different runtimes can be found in GNUStep's
[Objective-C Compiler and Runtime FAQ][gnustep-faq].
[modern]: https://en.wikipedia.org/wiki/Objective-C#Modern_Objective-C
[gcc-libobjc]: https://github.com/gcc-mirror/gcc/tree/master/libobjc
[gcc-objc-support]: https://gcc.gnu.org/onlinedocs/gcc/Standards.html#Objective-C-and-Objective-C_002b_002b-Languages
[`mulle-objc`]: https://github.com/mulle-objc/mulle-objc-runtime
[cocotron]: https://cocotron.org/
[`darling`]: https://github.com/darlinghq/darling-objc4
[gnustep-faq]: http://wiki.gnustep.org/index.php/Objective-C_Compiler_and_Runtime_FAQ
## Advanced linking configuration
This crate defines the `links` key in `Cargo.toml` so it's possible to
change the linking to `libobjc`, see [the relevant cargo docs][overriding].
In the future, this crate may vendor the required source code to automatically
build and link to the runtimes. Choosing static vs. dynamic linking here may
also become an option.
[overriding]: https://doc.rust-lang.org/cargo/reference/build-scripts.html#overriding-build-scripts
## Objective-C Compiler configuration
Objective-C compilers like `clang` and `gcc` requires configuring the calling
ABI to the runtime you're using:
- `clang` uses the [`-fobjc-runtime`] flag, of which there are a few different
[options][clang-objc-kinds].
- `gcc` uses the [`-fgnu-runtime` or `-fnext-runtime`][gcc-flags] options.
Note that Modern Objective-C features are ill supported.
This is relevant if you're building and linking to custom Objective-C sources
in a build script. To assist in compiling Objective-C sources, this crate's
build script expose the `DEP_OBJC_0_2_CC_ARGS` environment variable to
downstream build scripts.
Example usage in your `build.rs` (using the `cc` crate) would be as follows:
```rust , ignore
fn main() {
let mut builder = cc::Build::new();
builder.compiler("clang");
builder.file("my_objective_c_script.m");
for flag in std::env::var("DEP_OBJC_0_2_CC_ARGS").unwrap().split(' ') {
builder.flag(flag);
}
builder.compile("libmy_objective_c_script.a");
}
```
[`-fobjc-runtime`]: https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-fobjc-runtime
[clang-objc-kinds]: https://clang.llvm.org/doxygen/classclang_1_1ObjCRuntime.html#af19fe070a7073df4ecc666b44137c4e5
[gcc-flags]: https://gcc.gnu.org/onlinedocs/gcc/Objective-C-and-Objective-C_002b_002b-Dialect-Options.html
## Design choices
It is recognized that the most primary consumer of this library will be macOS
and secondly iOS applications. Therefore it was chosen not to use `bindgen` in
our build script to not add compilation cost to those targets.<sup>1</sup>
Deprecated functions are also not included for future compability, since they
could be removed in any macOS release, and then our code would break. If you
have a need for these, please open an issue and we can discuss it!
Some items (in particular the `objc_msgSend_X` family) have `cfg`s that prevent
their usage on different platforms; these are **semver-stable** in the sense
that they will only get less restrictive, never more.
<sup>1: That said, most of this is created with the help of `bindgen`'s
commandline interface, so huge thanks to them!</sup>

267
third-party/vendor/objc-sys/build.rs vendored Normal file
View file

@ -0,0 +1,267 @@
use std::{env, path::Path};
/// TODO: Better validation of this
///
/// The version is used for providing different behaviour when:
/// - CGException.cpp getObjCPersonality (GNUStep >= 1.7)
/// - Clang.cpp Clang::AddObjCRuntimeArgs (GNUStep >= 2.0)
/// - isLegacyDispatchDefaultForArch (macOS < 10.6, GNUStep < 1.6)
/// - hasNativeARC (macOS < 10.7, iOS < 5)
/// - shouldUseARCFunctionsForRetainRelease (macOS < 10.10, iOS < 8)
/// - shouldUseRuntimeFunctionsForAlloc (macOS < 10.10, iOS < 8)
/// - shouldUseRuntimeFunctionForCombinedAllocInit (macOS >= 10.14.4, iOS >= 12.2, watchOS >= 5.2)
/// - hasOptimizedSetter (macOS >= 10.8, iOS >= 6, GNUStep >= 1.7)
/// - hasSubscripting (macOS < 10.11, iOS < 9)
/// - hasTerminate (macOS < 10.8, iOS < 5)
/// - hasARCUnsafeClaimAutoreleasedReturnValue (macOS >= 10.11, iOS >= 9, watchOS >= 2)
/// - hasEmptyCollections (macOS >= 10.11, iOS >= 9, watchOS >= 2)
/// - ... (incomplete)
///
/// `macosx-fragile` and `gcc` was not considered in this analysis, made on
/// clang version 13's source code:
/// https://github.com/llvm/llvm-project/blob/llvmorg-13.0.0/clang/include/clang/Basic/ObjCRuntime.h
///
/// In short, it's not ultra important, but enables some optimizations if this
/// is specified.
type Version = Option<String>;
// For clang "-fobjc-runtime" support
#[allow(clippy::upper_case_acronyms)]
enum AppleRuntime {
MacOS(Version),
IOS(Version),
TvOS(Version),
WatchOS(Version),
// BridgeOS,
}
use AppleRuntime::*;
enum Runtime {
Apple(AppleRuntime),
GNUStep(u8, u8),
WinObjC,
#[allow(dead_code)]
ObjFW(Option<String>),
}
use Runtime::*;
fn get_env(env: &str) -> Option<String> {
println!("cargo:rerun-if-env-changed={}", env);
match env::var(env) {
Ok(var) => Some(var),
Err(env::VarError::NotPresent) => None,
Err(env::VarError::NotUnicode(var)) => panic!("Invalid unicode for {}: {:?}", env, var),
}
}
fn main() {
// The script doesn't depend on our code
println!("cargo:rerun-if-changed=build.rs");
let target = env::var("TARGET").unwrap();
// Used to figure out when BOOL should be i8 vs. bool
// Matches:
// aarch64-apple-ios-macabi
// x86_64-apple-ios-macabi
if target.ends_with("macabi") {
println!("cargo:rustc-cfg=target_abi_macabi");
}
// Used to set correct image info in `objc2`
// Matches:
// aarch64-apple-ios-sim
// aarch64-apple-watchos-sim
// x86_64-apple-watchos-sim
// i386-apple-ios
// x86_64-apple-ios
if target.ends_with("sim") || target == "i386-apple-ios" || target == "x86_64-apple-ios" {
println!("cargo:rustc-cfg=target_simulator");
}
// TODO: Figure out when to enable this
// println!("cargo:rustc-cfg=libobjc2_strict_apple_compat");
let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap();
let target_arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap();
let mut apple = env::var_os("CARGO_FEATURE_APPLE").is_some();
let mut gnustep = env::var_os("CARGO_FEATURE_GNUSTEP_1_7").is_some();
let objfw = env::var_os("CARGO_FEATURE_UNSTABLE_OBJFW").is_some();
// Choose defaults when generating docs
// Only when the crate is being compiled directly
if cfg!(feature = "unstable-docsrs") {
if let "macos" | "ios" | "tvos" | "watchos" = &*target_os {
apple = true;
} else {
gnustep = true; // Also winobjc
}
}
let runtime = match (apple, gnustep, objfw) {
(true, false, false) => {
Apple(match &*target_os {
"macos" => MacOS(Some(
get_env("MACOSX_DEPLOYMENT_TARGET").unwrap_or_else(|| "10.7".into()),
)),
"ios" => IOS(Some(
get_env("IPHONEOS_DEPLOYMENT_TARGET").unwrap_or_else(|| "7.0".into()),
)),
"tvos" => TvOS(get_env("TVOS_DEPLOYMENT_TARGET")),
"watchos" => WatchOS(get_env("WATCHOS_DEPLOYMENT_TARGET")),
// Choose a sensible default for other platforms that
// specified `apple`; this is likely not going to work anyhow
_ => MacOS(None),
})
}
(false, true, false) => {
// Choose defaults when generating docs
if cfg!(feature = "unstable-docsrs") {
if "windows" == target_os {
WinObjC
} else {
GNUStep(1, 7)
}
} else if env::var_os("CARGO_FEATURE_UNSTABLE_WINOBJC").is_some() {
WinObjC
} else if env::var_os("CARGO_FEATURE_GNUSTEP_2_1").is_some() {
GNUStep(2, 1)
} else if env::var_os("CARGO_FEATURE_GNUSTEP_2_0").is_some() {
GNUStep(2, 0)
} else if env::var_os("CARGO_FEATURE_GNUSTEP_1_9").is_some() {
GNUStep(1, 9)
} else if env::var_os("CARGO_FEATURE_GNUSTEP_1_8").is_some() {
GNUStep(1, 8)
} else {
// CARGO_FEATURE_GNUSTEP_1_7
GNUStep(1, 7)
}
}
(false, false, true) => {
// For now
unimplemented!("ObjFW is not yet supported")
// ObjFW(None)
}
(false, false, false) => panic!("Must specify the desired runtime (using cargo features)."),
_ => panic!("Invalid feature combination; only one runtime may be selected!"),
};
// Add `#[cfg(RUNTIME)]` directive
let runtime_cfg = match runtime {
Apple(_) => "apple",
// WinObjC can be treated like GNUStep 1.8
GNUStep(_, _) | WinObjC => "gnustep",
ObjFW(_) => "objfw",
};
println!("cargo:rustc-cfg={}", runtime_cfg);
if let Apple(runtime) = &runtime {
// A few things are defined differently depending on the __OBJC2__
// variable, which is set for all platforms except 32-bit macOS.
if let (MacOS(_), "x86") = (runtime, &*target_arch) {
println!("cargo:rustc-cfg=apple_old");
} else {
println!("cargo:rustc-cfg=apple_new");
}
}
let clang_runtime = match &runtime {
Apple(runtime) => {
// The fragile runtime is expected on i686-apple-darwin, see:
// https://github.com/llvm/llvm-project/blob/release/13.x/clang/lib/Driver/ToolChains/Darwin.h#L228-L231
// https://github.com/llvm/llvm-project/blob/release/13.x/clang/lib/Driver/ToolChains/Clang.cpp#L3639-L3640
let clang_runtime_str = match (runtime, &*target_arch) {
(MacOS(_), "x86") => "macosx-fragile",
(MacOS(_), _) => "macosx",
(IOS(_), _) => "ios",
(WatchOS(_), _) => "watchos",
// tvOS doesn't have its own -fobjc-runtime string
(TvOS(_), _) => "ios",
};
match runtime {
MacOS(version) | IOS(version) | WatchOS(version) | TvOS(version) => {
if let Some(version) = version {
format!("{}-{}", clang_runtime_str, version)
} else {
clang_runtime_str.into()
}
}
}
}
// Default in clang is 1.6
// GNUStep's own default is 1.8
GNUStep(major, minor) => format!("gnustep-{}.{}", major, minor),
// WinObjC's libobjc2 is just a fork of gnustep's from version 1.8
WinObjC => "gnustep-1.8".into(),
ObjFW(version) => {
// Default in clang
let version = version.as_deref().unwrap_or("0.8");
format!("objfw-{}", version)
}
};
// let gcc_args = match &runtime {
// Apple(_) => "-fnext-runtime -fobjc-abi-version=2",
// _ => "-fgnu-runtime",
// };
// Add CC arguments
// Assume the compiler is clang; if it isn't, this is probably going to
// fail anyways, since we're using newer runtimes than GCC supports.
//
// TODO: Should add we these, or is it someone else's responsibility?
// - `-mios-simulator-version-min={}`
// - `-miphoneos-version-min={}`
// - `-mmacosx-version-min={}`
// - ...
//
// TODO: -fobjc-weak ?
let mut cc_args = format!(
"-fobjc-arc -fobjc-arc-exceptions -fobjc-exceptions -fobjc-runtime={}",
clang_runtime
);
if let Runtime::ObjFW(_) = &runtime {
// Add compability headers to make `#include <objc/objc.h>` work.
let compat_headers = Path::new(env!("CARGO_MANIFEST_DIR")).join("compat-headers-objfw");
cc_args.push_str(" -I");
cc_args.push_str(compat_headers.to_str().unwrap());
}
println!("cargo:cc_args={}", cc_args); // DEP_OBJC_[version]_CC_ARGS
if let Runtime::ObjFW(_) = &runtime {
// Link to libobjfw-rt
println!("cargo:rustc-link-lib=dylib=objfw-rt");
} else {
// Link to libobjc
println!("cargo:rustc-link-lib=dylib=objc");
}
// We do this compilation step here instead of in `objc2` to cut down on
// the total number of build scripts required.
#[cfg(feature = "unstable-exception")]
{
if std::env::var("DOCS_RS").is_ok() {
// docs.rs doesn't have clang, so skip building this. The
// documentation will still work since it doesn't need to link.
//
// This is independent of the `unstable-docsrs` feature flag; we
// never want to try invoking clang on docs.rs, whether we're the
// crate being documented currently, or a dependency of another
// crate.
return;
}
println!("cargo:rerun-if-changed=extern/exception.m");
let mut builder = cc::Build::new();
builder.file("extern/exception.m");
for flag in cc_args.split(' ') {
builder.flag(flag);
}
builder.compile("librust_objc_sys_0_2_try_catch_exception.a");
}
}

View file

@ -0,0 +1 @@
#import <ObjFW-RT/ObjFW-RT.h>

View file

@ -0,0 +1 @@
#import <ObjFW-RT/ObjFW-RT.h>

View file

@ -0,0 +1,25 @@
// Don't include any headers, cross compilation is difficult to set up
// properly in such situations.
/// We're linking to `libobjc` in build.rs, so this should be available.
///
/// See <https://clang.llvm.org/docs/AutomaticReferenceCounting.html#arc-runtime-objc-retain>.
id objc_retain(id value);
/// Unsure how C name resolution works, so we make sure to version this symbol.
///
/// Return `unsigned char` since it is guaranteed to be `u8` on all platforms.
unsigned char rust_objc_sys_0_2_try_catch_exception(void (*f)(void *), void *context, id *error) {
@try {
f(context);
if (error) {
*error = (id)0; // nil
}
return 0;
} @catch (id exception) {
if (error) {
*error = objc_retain(exception);
}
return 1;
}
}

166
third-party/vendor/objc-sys/src/class.rs vendored Normal file
View file

@ -0,0 +1,166 @@
use std::os::raw::{c_char, c_int, c_uint};
#[cfg(any(doc, not(objfw)))]
use crate::{objc_ivar, objc_method, objc_object, objc_property, objc_property_attribute_t};
use crate::{objc_protocol, objc_selector, OpaqueData, BOOL, IMP};
/// An opaque type that represents an Objective-C class.
#[repr(C)]
pub struct objc_class {
// `isa` field is deprecated and not available on GNUStep, so we don't
// expose it here. Use `class_getSuperclass` instead.
_priv: [u8; 0],
_p: OpaqueData,
}
#[cfg(any(doc, not(objfw)))]
/// This is `c_char` in GNUStep's libobjc2 and `uint8_t` in Apple's objc4.
///
/// The pointer represents opaque data, and is definitely not just an integer,
/// so its signedness (i8 vs. u8) is not applicable.
///
/// So we just assign it here as a private alias to u8, to not document the
/// difference.
type ivar_layout_type = u8;
// May call `resolveClassMethod:` or `resolveInstanceMethod:`.
extern_c_unwind! {
#[cfg(any(doc, not(objfw)))]
pub fn class_getClassMethod(
cls: *const objc_class,
name: *const objc_selector,
) -> *const objc_method;
#[cfg(any(doc, not(objfw)))] // Available in newer versions
pub fn class_getInstanceMethod(
cls: *const objc_class,
name: *const objc_selector,
) -> *const objc_method;
pub fn class_respondsToSelector(cls: *const objc_class, sel: *const objc_selector) -> BOOL;
// #[deprecated = "use class_getMethodImplementation instead"]
// #[cfg(any(doc, apple))]
// pub fn class_lookupMethod
// #[deprecated = "use class_respondsToSelector instead"]
// #[cfg(any(doc, apple))]
// pub fn class_respondsToMethod
}
// TODO: Hooks registered with objc_setHook_getClass may be allowed to unwind?
extern_c! {
pub fn objc_getClass(name: *const c_char) -> *const objc_class;
pub fn objc_getRequiredClass(name: *const c_char) -> *const objc_class;
pub fn objc_lookUpClass(name: *const c_char) -> *const objc_class;
#[cfg(any(doc, not(objfw)))]
pub fn objc_getMetaClass(name: *const c_char) -> *const objc_class;
pub fn objc_copyClassList(out_len: *mut c_uint) -> *mut *const objc_class;
pub fn objc_getClassList(buffer: *mut *const objc_class, buffer_len: c_int) -> c_int;
pub fn objc_allocateClassPair(
superclass: *const objc_class,
name: *const c_char,
extra_bytes: usize,
) -> *mut objc_class;
#[cfg(any(doc, apple))]
pub fn objc_duplicateClass(
original: *const objc_class,
name: *const c_char,
extra_bytes: usize,
) -> *mut objc_class;
#[cfg(any(doc, not(objfw)))]
pub fn objc_disposeClassPair(cls: *mut objc_class);
pub fn objc_registerClassPair(cls: *mut objc_class);
#[cfg(any(doc, not(objfw)))]
pub fn class_addIvar(
cls: *mut objc_class,
name: *const c_char,
size: usize,
alignment: u8,
types: *const c_char,
) -> BOOL;
pub fn class_addMethod(
cls: *mut objc_class,
name: *const objc_selector,
imp: IMP,
types: *const c_char,
) -> BOOL;
#[cfg(any(doc, not(objfw)))]
pub fn class_addProperty(
cls: *mut objc_class,
name: *const c_char,
attributes: *const objc_property_attribute_t,
attributes_count: c_uint,
) -> BOOL;
#[cfg(any(doc, not(objfw)))]
pub fn class_addProtocol(cls: *mut objc_class, protocol: *const objc_protocol) -> BOOL;
pub fn class_conformsToProtocol(cls: *const objc_class, protocol: *const objc_protocol)
-> BOOL;
#[cfg(any(doc, not(objfw)))] // Available in newer versions
pub fn class_copyIvarList(
cls: *const objc_class,
out_len: *mut c_uint,
) -> *mut *const objc_ivar;
#[cfg(any(doc, not(objfw)))] // Available in newer versions
pub fn class_copyMethodList(
cls: *const objc_class,
out_len: *mut c_uint,
) -> *mut *const objc_method;
#[cfg(any(doc, not(objfw)))] // Available in newer versions
pub fn class_copyPropertyList(
cls: *const objc_class,
out_len: *mut c_uint,
) -> *mut *const objc_property;
#[cfg(any(doc, not(objfw)))]
pub fn class_copyProtocolList(
cls: *const objc_class,
out_len: *mut c_uint,
) -> *mut *const objc_protocol;
#[cfg(any(doc, not(objfw)))]
pub fn class_createInstance(cls: *const objc_class, extra_bytes: usize) -> *mut objc_object;
#[cfg(any(doc, not(objfw)))]
pub fn class_getClassVariable(cls: *const objc_class, name: *const c_char) -> *const objc_ivar;
#[cfg(any(doc, apple))]
pub fn class_getImageName(cls: *const objc_class) -> *const c_char;
pub fn class_getInstanceSize(cls: *const objc_class) -> usize;
#[cfg(any(doc, not(objfw)))]
pub fn class_getInstanceVariable(
cls: *const objc_class,
name: *const c_char,
) -> *const objc_ivar;
#[cfg(any(doc, not(objfw)))]
pub fn class_getIvarLayout(cls: *const objc_class) -> *const ivar_layout_type;
pub fn class_getName(cls: *const objc_class) -> *const c_char;
#[cfg(any(doc, not(objfw)))]
pub fn class_getProperty(cls: *const objc_class, name: *const c_char) -> *const objc_property;
pub fn class_getSuperclass(cls: *const objc_class) -> *const objc_class;
#[cfg(any(doc, not(objfw)))]
pub fn class_getVersion(cls: *const objc_class) -> c_int;
#[cfg(any(doc, apple))]
pub fn class_getWeakIvarLayout(cls: *const objc_class) -> *const ivar_layout_type;
pub fn class_isMetaClass(cls: *const objc_class) -> BOOL;
pub fn class_replaceMethod(
cls: *mut objc_class,
name: *const objc_selector,
imp: IMP,
types: *const c_char,
) -> IMP;
#[cfg(any(doc, not(objfw)))]
pub fn class_replaceProperty(
cls: *mut objc_class,
name: *const c_char,
attributes: *const objc_property_attribute_t,
attributes_len: c_uint,
);
#[cfg(any(doc, not(objfw)))]
pub fn class_setIvarLayout(cls: *mut objc_class, layout: *const ivar_layout_type);
#[cfg(any(doc, not(objfw)))]
pub fn class_setVersion(cls: *mut objc_class, version: c_int);
#[cfg(any(doc, apple))]
pub fn class_setWeakIvarLayout(cls: *mut objc_class, layout: *const ivar_layout_type);
// #[deprecated = "not recommended"]
// pub fn class_setSuperclass
}

View file

@ -0,0 +1,38 @@
//! Various common #defines and enum constants.
#[cfg(any(doc, apple))]
use std::os::raw::c_int;
use crate::{id, objc_class, BOOL};
/// The equivalent of `true` for Objective-C's [`BOOL`][`super::BOOL`] type.
#[allow(clippy::unnecessary_cast)]
pub const YES: BOOL = true as BOOL; // true -> 1
/// The equivalent of `false` for Objective-C's [`BOOL`][`super::BOOL`] type.
#[allow(clippy::unnecessary_cast)]
pub const NO: BOOL = false as BOOL; // false -> 0
/// A quick alias for a [`null_mut`][`core::ptr::null_mut`] object / instance.
pub const nil: id = 0 as *mut _;
/// A quick alias for a [`null_mut`][`core::ptr::null_mut`] class.
pub const Nil: *mut objc_class = 0 as *mut _;
pub type objc_AssociationPolicy = usize;
pub const OBJC_ASSOCIATION_ASSIGN: objc_AssociationPolicy = 0;
pub const OBJC_ASSOCIATION_RETAIN_NONATOMIC: objc_AssociationPolicy = 1;
pub const OBJC_ASSOCIATION_COPY_NONATOMIC: objc_AssociationPolicy = 3;
pub const OBJC_ASSOCIATION_RETAIN: objc_AssociationPolicy = 769;
pub const OBJC_ASSOCIATION_COPY: objc_AssociationPolicy = 771;
#[cfg(any(doc, apple))]
pub const OBJC_SYNC_SUCCESS: c_int = 0;
#[cfg(any(doc, apple))]
pub const OBJC_SYNC_NOT_OWNING_THREAD_ERROR: c_int = -1;
/// Only relevant before macOS 10.13
#[cfg(any(doc, apple))]
pub const OBJC_SYNC_TIMED_OUT: c_int = -2;
/// Only relevant before macOS 10.13
#[cfg(any(doc, apple))]
pub const OBJC_SYNC_NOT_INITIALIZED: c_int = -3;

View file

@ -0,0 +1,116 @@
//! Defined in:
//! Apple: `objc-exception.h`
//! GNUStep: `eh_personality.c`, which is a bit brittle to rely on, but I
//! think it's fine...
use core::ffi::c_void;
#[cfg(any(doc, apple_new))]
use std::os::raw::c_int;
#[cfg(feature = "unstable-exception")]
use std::os::raw::c_uchar;
#[cfg(any(doc, apple_new))]
use crate::objc_class;
use crate::objc_object;
/// Remember that this is non-null!
#[cfg(any(doc, apple_new))]
pub type objc_exception_matcher =
unsafe extern "C" fn(catch_type: *mut objc_class, exception: *mut objc_object) -> c_int;
/// Remember that this is non-null!
#[cfg(any(doc, apple_new))]
pub type objc_exception_preprocessor =
unsafe extern "C" fn(exception: *mut objc_object) -> *mut objc_object;
/// Remember that this is non-null!
#[cfg(any(doc, apple_new))]
pub type objc_uncaught_exception_handler = unsafe extern "C" fn(exception: *mut objc_object);
#[cfg(objfw)]
pub type objc_uncaught_exception_handler =
Option<unsafe extern "C" fn(exception: *mut objc_object)>;
/// Remember that this is non-null!
#[cfg(any(doc, all(apple_new, target_os = "macos")))]
pub type objc_exception_handler =
unsafe extern "C" fn(unused: *mut objc_object, context: *mut c_void);
#[cfg(all(feature = "unstable-exception", not(feature = "unstable-c-unwind")))]
type TryCatchClosure = extern "C" fn(*mut c_void);
#[cfg(all(feature = "unstable-exception", feature = "unstable-c-unwind"))]
type TryCatchClosure = extern "C-unwind" fn(*mut c_void);
extern_c_unwind! {
/// See [`objc-exception.h`].
///
/// [`objc-exception.h`]: https://github.com/apple-oss-distributions/objc4/blob/objc4-818.2/runtime/objc-exception.h
pub fn objc_exception_throw(exception: *mut objc_object) -> !;
#[cfg(apple_new)]
pub fn objc_exception_rethrow() -> !;
#[cfg(gnustep)]
pub fn objc_exception_rethrow(exc_buf: *mut c_void) -> !;
}
extern_c! {
#[cfg(any(doc, gnustep, apple_new))]
pub fn objc_begin_catch(exc_buf: *mut c_void) -> *mut objc_object;
#[cfg(any(doc, gnustep, apple_new))]
pub fn objc_end_catch();
#[cfg(any(doc, apple_old))]
pub fn objc_exception_try_enter(exception_data: *const c_void);
#[cfg(any(doc, apple_old))]
pub fn objc_exception_try_exit(exception_data: *const c_void);
// objc_exception_extract
// objc_exception_match
// objc_exception_get_functions
// objc_exception_set_functions
#[cfg(any(doc, apple_new))]
pub fn objc_setExceptionMatcher(f: objc_exception_matcher) -> objc_exception_matcher;
#[cfg(any(doc, apple_new))]
pub fn objc_setExceptionPreprocessor(
f: objc_exception_preprocessor,
) -> objc_exception_preprocessor;
#[cfg(any(doc, apple_new, objfw))]
pub fn objc_setUncaughtExceptionHandler(
f: objc_uncaught_exception_handler,
) -> objc_uncaught_exception_handler;
#[cfg(any(doc, all(apple_new, target_os = "macos")))]
pub fn objc_addExceptionHandler(f: objc_exception_handler, context: *mut c_void) -> usize;
#[cfg(any(doc, all(apple_new, target_os = "macos")))]
pub fn objc_removeExceptionHandler(token: usize);
// Only available when ENABLE_OBJCXX is set, and a useable C++ runtime is
// present when building libobjc2.
//
// #[cfg(any(doc, gnustep))]
// pub fn objc_set_apple_compatible_objcxx_exceptions(newValue: c_int) -> c_int;
/// Call the given function inside an Objective-C `@try/@catch` block.
///
/// Defined in `extern/exception.m` and compiled in `build.rs`.
///
/// Alternatively, we could manually write assembly for this function like
/// [`objrs` does][manual-asm] does, that would cut down on a build stage
/// (and would probably give us a bit better performance), but it gets
/// unwieldy _very_ quickly, so I chose the much more stable option.
///
/// Another thing to remember: While Rust's and Objective-C's unwinding
/// mechanisms are similar now, Rust's is explicitly unspecified, and they
/// may diverge significantly in the future; so handling this in pure Rust
/// (using mechanisms like core::intrinsics::r#try) is not an option!
///
/// [manual-asm]: https://gitlab.com/objrs/objrs/-/blob/b4f6598696b3fa622e6fddce7aff281770b0a8c2/src/exception.rs
#[cfg(feature = "unstable-exception")]
pub fn rust_objc_sys_0_2_try_catch_exception(
f: TryCatchClosure,
context: *mut c_void,
error: *mut *mut objc_object,
) -> c_uchar;
}

View file

@ -0,0 +1,45 @@
#[repr(C)]
#[doc(hidden)] // Private for now
pub struct __ImageInfo {
// These are not actually `unsigned int`, even though the docs say so
/// The version of the image info struct.
version: u32,
flags: u32,
}
#[allow(unused)]
impl __ImageInfo {
/// Unused
const FIX_AND_CONTINUE: u32 = 1 << 0;
const SUPPORTS_GARBAGE_COLLECTED: u32 = 1 << 1;
const REQUIRES_GARBAGE_COLLECTION: u32 = 1 << 2;
const OPTIMIZED_BY_DYLD: u32 = 1 << 3; // TODO
/// Unused
const CORRECTED_SYNTHESIZE: u32 = 1 << 4;
/// Whether we're compiling this to run on a simulator.
const IMAGE_IS_SIMULATED: u32 = 1 << 5;
/// Whether we are generating class properties.
const CLASS_PROPERTIES: u32 = 1 << 6;
const DYLD_PREOPTIMIZED: u32 = 1 << 7;
const SWIFT_ABI_VERSION_SHIFT: u32 = 8;
const SWIFT_ABI_VERSION_MASK: u32 = 0xff << Self::SWIFT_ABI_VERSION_SHIFT;
const SWIFT_MINOR_VERSION_SHIFT: u32 = 16;
const SWIFT_MINOR_VERSION_MASK: u32 = 0xff << Self::SWIFT_MINOR_VERSION_SHIFT;
const SWIFT_MAJOR_VERSION_SHIFT: u32 = 24;
const SWIFT_MAJOR_VERSION_MASK: u32 = 0xff << Self::SWIFT_MAJOR_VERSION_SHIFT;
/// Fetches the image info for the current runtime + target combination
#[inline]
pub const fn system() -> Self {
// We don't currently do anything relating to class properties, but
// let's just mimic what Clang does!
let mut flags = Self::CLASS_PROPERTIES;
if cfg!(target_simulator) {
flags |= Self::IMAGE_IS_SIMULATED;
}
Self { version: 0, flags }
}
}

190
third-party/vendor/objc-sys/src/lib.rs vendored Normal file
View file

@ -0,0 +1,190 @@
//! # Raw bindings to Objective-C runtimes
//!
//! These bindings contain almost no documentation, so it is highly
//! recommended to read the documentation of the original libraries:
//! - Apple's [official documentation][apple].
//! - Apple's `objc4` [source code][objc4], in particular `runtime.h`.
//! - GNUStep's `libobjc2` [source code][libobjc2], in particular `runtime.h`.
//!
//! See also the [`README.md`](https://crates.io/crates/objc-sys) for more
//! background information, and for how to configure the desired runtime.
//!
//! [apple]: https://developer.apple.com/documentation/objectivec/objective-c_runtime?language=objc
//! [libobjc2]: https://github.com/gnustep/libobjc2/tree/v2.1/objc
//! [objc4]: https://github.com/apple-oss-distributions/objc4
#![no_std]
#![warn(elided_lifetimes_in_paths)]
#![deny(non_ascii_idents)]
#![warn(unreachable_pub)]
#![deny(unsafe_op_in_unsafe_fn)]
#![warn(clippy::cargo)]
#![warn(clippy::ptr_as_ptr)]
#![allow(clippy::upper_case_acronyms)]
#![allow(non_camel_case_types)]
#![allow(non_upper_case_globals)]
#![allow(non_snake_case)]
#![doc(html_root_url = "https://docs.rs/objc-sys/0.2.0-beta.2")]
#![cfg_attr(feature = "unstable-c-unwind", feature(c_unwind))]
#![cfg_attr(feature = "unstable-docsrs", feature(doc_auto_cfg, doc_cfg_hide))]
#![cfg_attr(feature = "unstable-docsrs", doc(cfg_hide(doc)))]
// TODO: Remove this and add "no-std" category to Cargo.toml
// Requires a better solution for C-types in `no_std` crates.
// See https://github.com/japaric/cty/issues/14.
extern crate std;
#[cfg(not(feature = "std"))]
compile_error!("The `std` feature currently must be enabled.");
#[cfg(doctest)]
#[doc = include_str!("../README.md")]
extern "C" {}
use core::cell::UnsafeCell;
use core::marker::{PhantomData, PhantomPinned};
macro_rules! generate_linking_tests {
{
extern $abi:literal {$(
$(#[$m:meta])*
$v:vis fn $name:ident(
$($(#[$a_m:meta])* $a:ident: $t:ty),* $(,)?
) $(-> $r:ty)?;
)+}
mod $test_name:ident;
} => {
extern $abi {$(
$(#[$m])*
$v fn $name($($(#[$a_m])* $a: $t),*) $(-> $r)?;
)+}
#[allow(deprecated)]
#[cfg(test)]
mod $test_name {
#[allow(unused)]
use super::*;
$(
$(#[$m])*
#[test]
fn $name() {
// Get function pointer to make the linker require the
// symbol to be available.
let f: unsafe extern $abi fn($($(#[$a_m])* $t),*) $(-> $r)? = crate::$name;
// Workaround for https://github.com/rust-lang/rust/pull/92964
#[cfg(feature = "unstable-c-unwind")]
#[allow(clippy::useless_transmute)]
let f: unsafe extern "C" fn() = unsafe { core::mem::transmute(f) };
// Execute side-effect to ensure it is not optimized away.
std::println!("{:p}", f);
}
)+
}
};
}
macro_rules! extern_c {
{
$(
$(#[$m:meta])*
$v:vis fn $name:ident(
$($(#[$a_m:meta])* $a:ident: $t:ty),* $(,)?
) $(-> $r:ty)?;
)+
} => {
generate_linking_tests! {
extern "C" {$(
$(#[$m])*
$v fn $name($($(#[$a_m])* $a: $t),*) $(-> $r)?;
)+}
mod test_linkable;
}
};
}
// A lot of places may call `+initialize`, but the runtime guards those calls
// with `@try/@catch` blocks already, so we don't need to mark every function
// "C-unwind", only certain ones!
macro_rules! extern_c_unwind {
{
$(
$(#[$m:meta])*
$v:vis fn $name:ident(
$($(#[$a_m:meta])* $a:ident: $t:ty),* $(,)?
) $(-> $r:ty)?;
)+
} => {
#[cfg(not(feature = "unstable-c-unwind"))]
generate_linking_tests! {
extern "C" {$(
$(#[$m])*
$v fn $name($($(#[$a_m])* $a: $t),*) $(-> $r)?;
)+}
mod test_linkable_unwind;
}
#[cfg(feature = "unstable-c-unwind")]
generate_linking_tests! {
extern "C-unwind" {$(
$(#[$m])*
$v fn $name($($(#[$a_m])* $a: $t),*) $(-> $r)?;
)+}
mod test_linkable_unwind;
}
};
}
mod class;
mod constants;
mod exception;
mod image_info;
mod message;
mod method;
mod object;
mod property;
mod protocol;
mod rc;
mod selector;
mod types;
mod various;
pub use class::*;
pub use constants::*;
pub use exception::*;
pub use image_info::*;
pub use message::*;
pub use method::*;
pub use object::*;
pub use property::*;
pub use protocol::*;
pub use rc::*;
pub use selector::*;
pub use types::*;
pub use various::*;
/// We don't know much about the actual structs, so better mark them `!Send`,
/// `!Sync`, `!UnwindSafe`, `!RefUnwindSafe`, `!Unpin` and as mutable behind
/// shared references.
///
/// Downstream libraries can always manually opt in to these types afterwards.
/// (It's also less of a breaking change on our part if we re-add these).
///
/// TODO: Replace this with `extern type` to also mark it as `!Sized`.
type OpaqueData = UnsafeCell<PhantomData<(*const UnsafeCell<()>, PhantomPinned)>>;
#[cfg(test)]
mod tests {
use super::*;
use std::ffi::CStr;
#[test]
fn smoke() {
// Verify that this library links and works fine by itself
let name = CStr::from_bytes_with_nul(b"abc:def:\0").unwrap();
let sel = unsafe { sel_registerName(name.as_ptr()) };
let rtn = unsafe { CStr::from_ptr(sel_getName(sel)) };
assert_eq!(name, rtn);
}
}

View file

@ -0,0 +1,87 @@
//! The `objc_msgSend` familiy of functions.
//!
//! Most of these are `cfg`-gated, these configs are semver-stable.
//!
//! TODO: Some of these are only supported on _some_ GNUStep targets!
use crate::{objc_class, objc_object};
#[cfg(any(doc, gnustep, objfw))]
use crate::{objc_selector, IMP};
/// Specifies data used when sending messages to superclasses.
#[repr(C)]
#[derive(Debug, Copy, Clone)]
// TODO: Does this belong in this file or in types.rs?
pub struct objc_super {
/// The object / instance to send a message to.
pub receiver: *mut objc_object,
/// The particular superclass of the instance to message.
///
/// Named `class` in older Objective-C versions.
pub super_class: *const objc_class,
}
// All message sending functions should use "C-unwind"!
//
// Note that lookup functions won't throw exceptions themselves, but they can
// call hooks, `resolveClassMethod:` and `resolveInstanceMethod:`, so we have
// to make those "C-unwind" as well!
extern_c_unwind! {
#[cfg(any(doc, gnustep, objfw))]
pub fn objc_msg_lookup(receiver: *mut objc_object, sel: *const objc_selector) -> IMP;
#[cfg(any(doc, objfw))]
pub fn objc_msg_lookup_stret(receiver: *mut objc_object, sel: *const objc_selector) -> IMP;
#[cfg(any(doc, gnustep, objfw))]
pub fn objc_msg_lookup_super(sup: *const objc_super, sel: *const objc_selector) -> IMP;
#[cfg(any(doc, objfw))]
pub fn objc_msg_lookup_super_stret(sup: *const objc_super, sel: *const objc_selector) -> IMP;
// #[cfg(any(doc, gnustep))]
// objc_msg_lookup_sender
// objc_msgLookup family available in macOS >= 10.12
// objc_msgSend_noarg
#[cfg(any(doc, not(objfw)))]
pub fn objc_msgSend();
// objc_msgSend_debug
#[cfg(any(doc, apple))]
pub fn objc_msgSendSuper();
// objc_msgSendSuper2
// objc_msgSendSuper2_debug
#[cfg(any(doc, apple))]
pub fn method_invoke();
#[cfg(any(doc, apple))]
pub fn _objc_msgForward();
pub fn class_getMethodImplementation();
// Struct return. Not available on __arm64__:
#[cfg(any(doc, all(not(objfw), not(target_arch = "aarch64"))))]
pub fn objc_msgSend_stret();
// objc_msgSend_stret_debug
#[cfg(any(doc, all(apple, not(target_arch = "aarch64"))))]
pub fn objc_msgSendSuper_stret();
// objc_msgSendSuper2_stret
// objc_msgSendSuper2_stret_debug
#[cfg(any(doc, all(apple, not(target_arch = "aarch64"))))]
pub fn method_invoke_stret();
#[cfg(any(doc, all(apple, not(target_arch = "aarch64"))))]
pub fn _objc_msgForward_stret();
#[cfg(any(doc, objfw, not(target_arch = "aarch64")))]
pub fn class_getMethodImplementation_stret();
// __x86_64__ and __i386__
#[cfg(any(doc, all(not(objfw), any(target_arch = "x86_64", target_arch = "x86"))))]
pub fn objc_msgSend_fpret();
// objc_msgSend_fpret_debug
// __x86_64__
#[cfg(any(doc, all(apple, target_arch = "x86_64")))]
pub fn objc_msgSend_fp2ret();
// objc_msgSend_fp2ret_debug
}

View file

@ -0,0 +1,54 @@
use std::os::raw::c_char;
#[cfg(any(doc, not(objfw)))]
use std::os::raw::c_uint;
#[cfg(any(doc, not(objfw)))]
use crate::IMP;
use crate::{objc_selector, OpaqueData};
/// A type that represents a method in a class definition.
#[repr(C)]
pub struct objc_method {
_priv: [u8; 0],
_p: OpaqueData,
}
/// Describes an Objective-C method.
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct objc_method_description {
/// The name of the method.
pub name: *const objc_selector,
/// The types of the method arguments.
pub types: *const c_char,
}
extern_c! {
#[cfg(any(doc, not(objfw)))]
pub fn method_copyArgumentType(method: *const objc_method, index: c_uint) -> *mut c_char;
#[cfg(any(doc, not(objfw)))]
pub fn method_copyReturnType(method: *const objc_method) -> *mut c_char;
#[cfg(any(doc, not(objfw)))]
pub fn method_exchangeImplementations(method1: *mut objc_method, method2: *mut objc_method);
#[cfg(any(doc, not(objfw)))]
pub fn method_getArgumentType(
method: *const objc_method,
index: c_uint,
dst: *mut c_char,
dst_len: usize,
);
#[cfg(any(doc, apple))]
pub fn method_getDescription(m: *const objc_method) -> *const objc_method_description;
#[cfg(any(doc, not(objfw)))]
pub fn method_getImplementation(method: *const objc_method) -> IMP;
#[cfg(any(doc, not(objfw)))]
pub fn method_getName(method: *const objc_method) -> *const objc_selector;
#[cfg(any(doc, not(objfw)))]
pub fn method_getNumberOfArguments(method: *const objc_method) -> c_uint;
#[cfg(any(doc, not(objfw)))]
pub fn method_getReturnType(method: *const objc_method, dst: *mut c_char, dst_len: usize);
#[cfg(any(doc, not(objfw)))]
pub fn method_getTypeEncoding(method: *const objc_method) -> *const c_char;
#[cfg(any(doc, not(objfw)))]
pub fn method_setImplementation(method: *const objc_method, imp: IMP) -> IMP;
}

View file

@ -0,0 +1,104 @@
#[cfg(any(doc, not(objfw)))]
use core::ffi::c_void;
use std::os::raw::c_char;
#[cfg(any(doc, not(objfw)))]
use crate::objc_ivar;
use crate::{objc_class, OpaqueData};
/// An opaque type that represents an object / an instance of a class.
#[repr(C)]
pub struct objc_object {
// `isa` field is deprecated, so we don't expose it here.
// Use `object_getClass` instead.
_priv: [u8; 0],
_p: OpaqueData,
}
extern_c! {
pub fn object_getClass(obj: *const objc_object) -> *const objc_class;
pub fn object_getClassName(obj: *const objc_object) -> *const c_char;
pub fn object_setClass(obj: *mut objc_object, cls: *const objc_class) -> *const objc_class;
#[cfg(any(doc, not(objfw)))]
pub fn object_getIndexedIvars(obj: *const objc_object) -> *const c_void;
#[cfg(any(doc, not(objfw)))]
pub fn object_getIvar(obj: *const objc_object, ivar: *const objc_ivar) -> *const objc_object;
#[cfg(any(doc, not(objfw)))]
pub fn object_setIvar(obj: *mut objc_object, ivar: *const objc_ivar, value: *mut objc_object);
#[deprecated = "Not needed since ARC"]
#[cfg(any(doc, apple))]
pub fn object_copy(obj: *const objc_object, size: usize) -> *mut objc_object;
#[deprecated = "Not needed since ARC"]
#[cfg(any(doc, not(objfw)))]
pub fn object_dispose(obj: *mut objc_object) -> *mut objc_object;
#[deprecated = "Not needed since ARC"]
#[cfg(any(doc, not(objfw)))]
pub fn object_setInstanceVariable(
obj: *mut objc_object,
name: *const c_char,
value: *mut c_void,
) -> *const objc_ivar;
// Available in macOS 10.12
// #[deprecated = "Not needed since ARC"]
// #[cfg(any(doc, apple))]
// pub fn object_setInstanceVariableWithStrongDefault(
// obj: *mut objc_object,
// name: *const c_char,
// value: *mut c_void,
// ) -> *const objc_ivar;
#[deprecated = "Not needed since ARC"]
#[cfg(any(doc, not(objfw)))]
pub fn object_getInstanceVariable(
obj: *const objc_object,
name: *const c_char,
out_value: *mut *const c_void,
) -> *const objc_ivar;
#[deprecated = "Not needed since ARC"]
#[cfg(any(doc, apple))]
pub fn objc_getFutureClass(name: *const c_char) -> *const objc_class;
#[deprecated = "Not needed since ARC"]
#[cfg(any(doc, apple))]
pub fn objc_constructInstance(cls: *const objc_class, bytes: *mut c_void) -> *mut objc_object;
#[deprecated = "Not needed since ARC"]
#[cfg(any(doc, apple))]
pub fn objc_destructInstance(obj: *mut objc_object) -> *mut c_void;
// TODO: Unsure if we should expose these; are they useful, and stable?
// Defined in objc-abi.h
// pub fn objc_getProperty(
// obj: *const objc_object,
// sel: *const objc_selector,
// offset: isize,
// atomic: BOOL,
// ) -> *mut c_void;
// pub fn objc_setProperty(
// obj: *const objc_object,
// sel: *const objc_selector,
// offset: isize,
// newValue: *const c_void,
// atomic: BOOL,
// shouldCopy: i8,
// );
// This is generated in setters to struct properties.
// pub fn objc_copyStruct(
// dest: *mut c_void,
// src: *const c_void,
// size: isize,
// atomic: BOOL,
// hasStrong: BOOL,
// );
// #[deprecated = "use object_copy instead"]
// #[cfg(any(doc, all(apple, target_os = "macos")))]
// object_copyFromZone
// #[deprecated = "use class_createInstance instead"]
// #[cfg(any(doc, all(apple, target_os = "macos")))]
// class_createInstanceFromZone
}

View file

@ -0,0 +1,41 @@
use std::os::raw::c_char;
#[cfg(any(doc, not(objfw)))]
use std::os::raw::c_uint;
use crate::OpaqueData;
/// An opaque type that describes a property in a class.
#[repr(C)]
pub struct objc_property {
_priv: [u8; 0],
_p: OpaqueData,
}
/// Describes an Objective-C property attribute.
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct objc_property_attribute_t {
/// The name of the attribute.
pub name: *const c_char,
/// The value of the attribute
///
/// Usually NULL.
pub value: *const c_char,
}
extern_c! {
#[cfg(any(doc, not(objfw)))]
pub fn property_copyAttributeList(
property: *const objc_property,
out_len: *mut c_uint,
) -> *mut objc_property_attribute_t;
#[cfg(any(doc, not(objfw)))]
pub fn property_copyAttributeValue(
property: *const objc_property,
attribute_name: *const c_char,
) -> *mut c_char;
#[cfg(any(doc, not(objfw)))]
pub fn property_getAttributes(property: *const objc_property) -> *const c_char;
#[cfg(any(doc, not(objfw)))]
pub fn property_getName(property: *const objc_property) -> *const c_char;
}

View file

@ -0,0 +1,98 @@
use std::os::raw::c_char;
#[cfg(any(doc, not(objfw)))]
use std::os::raw::c_uint;
#[cfg(any(doc, not(objfw)))]
use crate::{objc_method_description, objc_property, objc_property_attribute_t, objc_selector};
use crate::{OpaqueData, BOOL};
/// Opaque type for Objective-C protocols.
///
/// Note that, although protocols are objects, sending messages to them is
/// deprecated and may not work in the future.
///
/// The naming of this follows GNUStep; this does not exist in Apple's
/// original, there `Protocol` is just a type alias of `objc_object`.
#[repr(C)]
pub struct objc_protocol {
_priv: [u8; 0],
_p: OpaqueData,
}
extern_c! {
#[cfg(any(doc, not(objfw)))]
pub fn objc_getProtocol(name: *const c_char) -> *const objc_protocol;
#[cfg(any(doc, not(objfw)))]
pub fn objc_copyProtocolList(out_len: *mut c_uint) -> *mut *const objc_protocol;
#[cfg(any(doc, not(objfw)))]
pub fn objc_allocateProtocol(name: *const c_char) -> *mut objc_protocol;
#[cfg(any(doc, not(objfw)))]
pub fn objc_registerProtocol(proto: *mut objc_protocol);
// TODO: Verify unwinding
pub fn protocol_conformsToProtocol(
proto: *const objc_protocol,
other: *const objc_protocol,
) -> BOOL;
// TODO: Verify unwinding
pub fn protocol_isEqual(proto: *const objc_protocol, other: *const objc_protocol) -> BOOL;
pub fn protocol_getName(proto: *const objc_protocol) -> *const c_char;
#[cfg(any(doc, not(objfw)))]
pub fn protocol_addMethodDescription(
proto: *mut objc_protocol,
name: *const objc_selector,
types: *const c_char,
is_required_method: BOOL,
is_instance_method: BOOL,
);
#[cfg(any(doc, not(objfw)))]
pub fn protocol_addProperty(
proto: *mut objc_protocol,
name: *const c_char,
attributes: *const objc_property_attribute_t,
attributes_len: c_uint,
is_required_property: BOOL,
is_instance_property: BOOL,
);
#[cfg(any(doc, not(objfw)))]
pub fn protocol_addProtocol(proto: *mut objc_protocol, addition: *const objc_protocol);
#[cfg(any(doc, not(objfw)))]
pub fn protocol_copyMethodDescriptionList(
proto: *const objc_protocol,
is_required_method: BOOL,
is_instance_method: BOOL,
out_len: *mut c_uint,
) -> *mut objc_method_description;
#[cfg(any(doc, not(objfw)))]
pub fn protocol_copyPropertyList(
proto: *const objc_protocol,
out_len: *mut c_uint,
) -> *mut *const objc_property;
#[cfg(any(doc, not(objfw)))]
pub fn protocol_copyProtocolList(
proto: *const objc_protocol,
out_len: *mut c_uint,
) -> *mut *const objc_protocol;
#[cfg(any(doc, not(objfw)))]
pub fn protocol_getMethodDescription(
proto: *const objc_protocol,
sel: *const objc_selector,
is_required_method: BOOL,
is_instance_method: BOOL,
) -> objc_method_description;
#[cfg(any(doc, not(objfw)))]
pub fn protocol_getProperty(
proto: *const objc_protocol,
name: *const c_char,
is_required_property: BOOL,
is_instance_property: BOOL,
) -> *const objc_property;
// #[cfg(any(doc, macos >= 10.12))]
// protocol_copyPropertyList2
// #[cfg(any(doc, gnustep))]
// _protocol_getMethodTypeEncoding
}

63
third-party/vendor/objc-sys/src/rc.rs vendored Normal file
View file

@ -0,0 +1,63 @@
//! ARC functions.
//!
//! Is available in Clang's [documentation][ARC] so these are safe to rely on.
//!
//! All available since macOS `10.7`.
//!
//! Defined in:
//! - Apple: `objc-internal.h`
//! - GNUStep: `objc-arc.h`
//! - ObjFW: `runtime/arc.m`
//!
//! [ARC]: https://clang.llvm.org/docs/AutomaticReferenceCounting.html#runtime-support>
use core::ffi::c_void;
use crate::objc_object;
// All of these very rarely unwind, but may if the user defined methods
// `retain`, `release`, `autorelease` or `dealloc` do.
extern_c_unwind! {
// Autoreleasepool
// ObjFW: Defined in `autorelease.h`, not available with libobjfw-rt!
#[cfg(any(doc, not(objfw)))]
pub fn objc_autoreleasePoolPop(pool: *mut c_void);
#[cfg(any(doc, not(objfw)))]
pub fn objc_autoreleasePoolPush() -> *mut c_void;
// Autorelease
pub fn objc_autorelease(value: *mut objc_object) -> *mut objc_object;
pub fn objc_autoreleaseReturnValue(value: *mut objc_object) -> *mut objc_object;
// Weak pointers
pub fn objc_copyWeak(to: *mut *mut objc_object, from: *mut *mut objc_object);
pub fn objc_destroyWeak(addr: *mut *mut objc_object);
pub fn objc_initWeak(addr: *mut *mut objc_object, value: *mut objc_object) -> *mut objc_object;
// Defined in runtime.h
pub fn objc_loadWeak(addr: *mut *mut objc_object) -> *mut objc_object;
pub fn objc_loadWeakRetained(addr: *mut *mut objc_object) -> *mut objc_object;
pub fn objc_moveWeak(to: *mut *mut objc_object, from: *mut *mut objc_object);
// Retain / release
pub fn objc_release(value: *mut objc_object);
pub fn objc_retain(value: *mut objc_object) -> *mut objc_object;
pub fn objc_retainAutorelease(value: *mut objc_object) -> *mut objc_object;
pub fn objc_retainAutoreleaseReturnValue(value: *mut objc_object) -> *mut objc_object;
pub fn objc_retainAutoreleasedReturnValue(value: *mut objc_object) -> *mut objc_object;
// Defined in objc-abi.h
pub fn objc_retainBlock(value: *mut objc_object) -> *mut objc_object;
// Storing values
pub fn objc_storeStrong(addr: *mut *mut objc_object, value: *mut objc_object);
// Defined in runtime.h
pub fn objc_storeWeak(addr: *mut *mut objc_object, value: *mut objc_object)
-> *mut objc_object;
// TODO: Decide about nonstandard extensions like these:
// #[cfg(any(doc, gnustep))]
// pub fn objc_delete_weak_refs(obj: *mut objc_object) -> BOOL;
}

View file

@ -0,0 +1,24 @@
use std::os::raw::c_char;
use crate::{OpaqueData, BOOL};
/// An opaque type that represents a method selector.
///
/// Selectors are immutable.
#[repr(C)]
pub struct objc_selector {
_priv: [u8; 0],
_p: OpaqueData,
}
extern_c! {
pub fn sel_getName(sel: *const objc_selector) -> *const c_char;
pub fn sel_isEqual(lhs: *const objc_selector, rhs: *const objc_selector) -> BOOL;
pub fn sel_registerName(name: *const c_char) -> *const objc_selector;
#[cfg(any(doc, not(objfw)))]
pub fn sel_getUid(name: *const c_char) -> *const objc_selector;
#[cfg(any(doc, apple))]
pub fn sel_isMapped(sel: *const objc_selector) -> BOOL;
}

195
third-party/vendor/objc-sys/src/types.rs vendored Normal file
View file

@ -0,0 +1,195 @@
//! Objective-C type aliases.
use crate::{objc_object, objc_selector};
/// The BOOL typedef for Apple's objc4.
///
/// Don't be fooled by the backup definition in `objc.h`; __OBJC_BOOL_IS_BOOL
/// is always defined by `clang` when compiling Objective-C sources. The below
/// cfgs are determined experimentally via. cross compiling.
#[cfg(apple)]
mod inner {
// __OBJC_BOOL_IS_BOOL
#[cfg(any(
// aarch64-apple-*
target_arch = "aarch64",
// + x86_64-apple-ios (but not x86_64-apple-ios-macabi)
all(target_os = "ios", target_pointer_width = "64", not(target_abi_macabi)),
// + x86_64-apple-tvos
all(target_os = "tvos", target_pointer_width = "64"),
// + *-apple-watchos (no Rust targets with this yet)
target_os = "watchos",
))]
// C: _Bool
pub(crate) type BOOL = bool;
// Inverse of the above
#[cfg(not(any(
target_arch = "aarch64",
all(target_os = "ios", target_pointer_width = "64", not(target_abi_macabi)),
all(target_os = "tvos", target_pointer_width = "64"),
target_os = "watchos",
)))]
// C: (explicitly) signed char
pub(crate) type BOOL = i8;
}
// GNUStep's and Microsoft's libobjc2
#[cfg(all(gnustep, libobjc2_strict_apple_compat))]
mod inner {
// C: (explicitly) signed char
pub(crate) type BOOL = i8;
}
#[cfg(all(gnustep, not(libobjc2_strict_apple_compat)))]
mod inner {
// windows && !32bit-MinGW
#[cfg(all(windows, not(all(target_pointer_width = "64", target_env = "gnu"))))]
pub(crate) type BOOL = std::os::raw::c_int;
// The inverse
#[cfg(not(all(windows, not(all(target_pointer_width = "64", target_env = "gnu")))))]
// C: unsigned char
pub(crate) type BOOL = u8;
}
// ObjFW
#[cfg(objfw)]
mod inner {
// Defined in ObjFW-RT.h
// C: signed char
// This has changed since v0.90, but we don't support that yet.
pub(crate) type BOOL = i8;
// Note that ObjFW uses `bool` in return types, but that doesn't change
// the ABI, so we'll just use `BOOL` there for ease of use.
}
/// The Objective-C `BOOL` type.
///
/// The type of this varies across platforms, so to convert an it into a Rust
/// [`bool`], compare it with [`NO`][crate::NO].
///
/// Note that this does _not_ implement `objc2::Encode` on all platforms! You
/// should only use this on FFI boundaries, otherwise prefer
/// `objc2::runtime::Bool`.
///
/// See also the [corresponding documentation entry][docs].
///
/// [docs]: https://developer.apple.com/documentation/objectivec/bool?language=objc
pub type BOOL = inner::BOOL;
// # Why isize/usize is correct for NSInteger/NSUInteger
//
// ## Apple
// The documentation clearly states:
//
// > When building 32-bit applications, NSInteger is a 32-bit integer. A
// 64-bit application treats NSInteger as a 64-bit integer.
//
// And the header file defines them like so:
//
// #if __LP64__ || TARGET_OS_WIN32 || NS_BUILD_32_LIKE_64
// typedef long NSInteger;
// typedef unsigned long NSUInteger;
// #else
// typedef int NSInteger;
// typedef unsigned int NSUInteger;
// #endif
//
// Rust (or at least `libc`) has no targets where c_int/c_uint are not 32-bit,
// so that part is correct. By manual inspection it is found that the only
// platform where c_long/c_ulong differs from isize/usize is on Windows.
// However Apple's libraries are only designed to work on 32-bit Windows, so
// this case should be fine as well.
//
// Likewise for NSUInteger.
//
// ## GNUStep / WinObjC
//
// Defined as intptr_t/uintptr_t, which is exactly the same as isize/usize.
//
// ## ObjFW
//
// Doesn't define these, but e.g. `OFString -length` returns size_t, so our
// definitions are should be correct on effectively all targets.
//
// Things might change slightly in the future, see
// <https://internals.rust-lang.org/t/pre-rfc-usize-is-not-size-t/15369>.
/// A signed integer value type.
///
/// This is guaranteed to always be a type-alias to [`isize`]. That means it
/// is valid to use `#[repr(isize)]` on enums and structs with size
/// `NSInteger`.
///
/// See also the [corresponding documentation entry][docs].
///
/// [docs]: https://developer.apple.com/documentation/objectivec/nsinteger?language=objc
///
/// # Examples
///
/// ```
/// #[repr(isize)] // NSInteger
/// pub enum NSComparisonResult {
/// NSOrderedAscending = -1,
/// NSOrderedSame = 0,
/// NSOrderedDescending = 1,
/// }
/// ```
pub type NSInteger = isize;
/// Describes an unsigned integer.
///
/// This is guaranteed to always be a type-alias to [`usize`]. That means it
/// is valid to use `#[repr(usize)]` on enums and structs with size
/// `NSUInteger`.
///
/// See also the [corresponding documentation entry][docs].
///
/// [docs]: https://developer.apple.com/documentation/objectivec/nsuinteger?language=objc
///
/// # Examples
///
/// ```
/// use objc_sys::NSUInteger;
/// // Or:
/// // use objc2::ffi::NSUInteger;
/// // use objc2::foundation::NSUInteger;
/// extern "C" {
/// fn some_external_function() -> NSUInteger;
/// }
/// ```
///
/// ```
/// #[repr(usize)] // NSUInteger
/// enum NSRoundingMode {
/// NSRoundPlain = 0,
/// NSRoundDown = 1,
/// NSRoundUp = 2,
/// NSRoundBankers = 3,
/// };
/// ```
pub type NSUInteger = usize;
/// The maximum value for an NSInteger.
pub const NSIntegerMax: NSInteger = NSInteger::MAX;
/// The minimum value for an NSInteger.
pub const NSIntegerMin: NSInteger = NSInteger::MIN;
/// The maximum value for an NSUInteger.
pub const NSUIntegerMax: NSUInteger = NSUInteger::MAX;
/// An immutable pointer to a selector.
///
/// Type alias provided for convenience. See `objc2::runtime::Sel` for a
/// higher level binding.
pub type SEL = *const objc_selector;
/// A mutable pointer to an object / instance.
///
/// Type alias provided for convenience. See `objc2::runtime::Object` for a
/// higher level binding, and `objc2::rc::Id` for an easier way of handling
/// objects.
pub type id = *mut objc_object;

View file

@ -0,0 +1,118 @@
use core::ffi::c_void;
#[cfg(any(doc, not(objfw)))]
use std::os::raw::c_char;
use std::os::raw::c_int;
#[cfg(any(doc, apple))]
use std::os::raw::c_uint;
#[cfg(any(doc, not(objfw)))]
use crate::{objc_AssociationPolicy, BOOL};
use crate::{objc_object, OpaqueData};
/// An opaque type that represents an instance variable.
#[repr(C)]
pub struct objc_ivar {
_priv: [u8; 0],
_p: OpaqueData,
}
#[cfg(not(feature = "unstable-c-unwind"))]
type InnerImp = unsafe extern "C" fn();
#[cfg(feature = "unstable-c-unwind")]
type InnerImp = unsafe extern "C-unwind" fn();
/// A nullable pointer to the start of a method implementation.
///
/// Not all APIs are guaranteed to take NULL values; read the docs!
pub type IMP = Option<InnerImp>;
// /// Remember that this is non-null!
// #[cfg(any(doc, apple_new))]
// pub type objc_hook_getClass =
// unsafe extern "C" fn(name: *const c_char, out_cls: *mut *const crate::objc_class) -> BOOL;
//
// /// Remember that this is non-null!
// #[cfg(any(doc, apple_new))]
// pub type objc_hook_lazyClassNamer =
// unsafe extern "C" fn(cls: *const crate::objc_class) -> *const c_char;
extern_c_unwind! {
// Instead of being able to change this, it's a weak symbol on GNUStep.
#[cfg(any(doc, apple, objfw))]
pub fn objc_enumerationMutation(obj: *mut objc_object);
}
extern_c! {
#[cfg(any(doc, not(objfw)))]
pub fn imp_getBlock(imp: IMP) -> *mut objc_object;
#[cfg(any(doc, not(objfw)))]
pub fn imp_implementationWithBlock(block: *mut objc_object) -> IMP;
#[cfg(any(doc, not(objfw)))]
pub fn imp_removeBlock(imp: IMP) -> BOOL;
#[cfg(any(doc, not(objfw)))]
pub fn ivar_getName(ivar: *const objc_ivar) -> *const c_char;
#[cfg(any(doc, not(objfw)))]
pub fn ivar_getOffset(ivar: *const objc_ivar) -> isize;
#[cfg(any(doc, not(objfw)))]
pub fn ivar_getTypeEncoding(ivar: *const objc_ivar) -> *const c_char;
#[cfg(any(doc, apple))]
pub fn objc_copyClassNamesForImage(
image: *const c_char,
out_len: *mut c_uint,
) -> *mut *const c_char;
#[cfg(any(doc, apple))]
pub fn objc_copyImageNames(out_len: *mut c_uint) -> *mut *const c_char;
#[cfg(any(doc, apple, objfw))]
pub fn objc_setEnumerationMutationHandler(
handler: Option<unsafe extern "C" fn(obj: *mut objc_object)>,
);
#[cfg(any(doc, not(objfw)))]
pub fn objc_getAssociatedObject(
object: *const objc_object,
key: *const c_void,
) -> *const objc_object;
#[cfg(any(doc, not(objfw)))]
pub fn objc_setAssociatedObject(
object: *mut objc_object,
key: *const c_void,
value: *mut objc_object,
policy: objc_AssociationPolicy,
);
#[cfg(any(doc, not(objfw)))]
pub fn objc_removeAssociatedObjects(object: *mut objc_object);
#[cfg(any(doc, apple, objfw))]
pub fn objc_setForwardHandler(fwd: *mut c_void, fwd_stret: *mut c_void);
// These two are defined in:
// - Apple: objc-sync.h
// - GNUStep: dtable.h / associate.m
// - ObjFW: ObjFW-RT.h
pub fn objc_sync_enter(obj: *mut objc_object) -> c_int;
pub fn objc_sync_exit(obj: *mut objc_object) -> c_int;
// Available in macOS 10.14.4
// /// Remember that this is non-null!
// #[cfg(any(doc, apple_new))]
// pub fn objc_setHook_getClass(
// new_value: objc_hook_getClass,
// out_old_value: *mut objc_hook_getClass,
// );
// Available in macOS 11
// /// Remember that this is non-null!
// #[cfg(any(doc, apple_new))]
// pub fn objc_setHook_lazyClassNamer(
// new_value: objc_hook_lazyClassNamer,
// out_old_value: *mut objc_hook_lazyClassNamer,
// );
// #[deprecated = "not recommended"]
// #[cfg(any(doc, apple))]
// pub fn _objc_flush_caches
// #[cfg(any(doc, gnustep))]
// objc_test_capability
}