Support 'swift_name' attributes on generated functions

Fixes #420
This commit is contained in:
Alastair Daivis
2020-01-06 18:45:38 -05:00
committed by Emilio Cobos Álvarez
parent ac1a7d47e8
commit cf406e9640
14 changed files with 750 additions and 48 deletions
+15
View File
@@ -293,7 +293,15 @@ All function attributes are just local overrides for the same options found in t
* prefix
* postfix
## Generating Swift Bindings
In addition to parsing function names in C/C++ header files, the Swift compiler can make use of the `swift_name` attribute on functions to generate more idiomatic names for imported functions and methods.
This attribute is commonly used in Objective-C/C/C++ via the `NS_SWIFT_NAME` and `CF_SWIFT_NAME` macros.
Given configuration in the cbindgen.toml, `cbindgen` can generate these attributes for you by guessing an appropriate method signature based on the existing function name (and type, if it is a method in an `impl` block).
This is controlled by the `swift_name_macro` option in the cbindgen.toml.
## cbindgen.toml
@@ -545,6 +553,13 @@ args = "horizontal"
# default: nothing is emitted for must_use functions
must_use = "MUST_USE_FUNC"
# An optional string that, if present, will be used to generate Swift function
# and method signatures for generated functions, for example "CF_SWIFT_NAME".
# If no such macro is available in your toolchain, you can define one using the
# `header` option in cbindgen.toml
# default: no swift_name function attributes are generated
swift_name_macro = "CF_SWIFT_NAME"
# A rule to use to rename function argument names. The renaming assumes the input
# is the Rust standard snake_case, however it accepts all the different rename_args
# inputs. This means many options here are no-ops or redundant.
+4 -1
View File
@@ -279,12 +279,14 @@ pub struct FunctionConfig {
pub prefix: Option<String>,
/// Optional text to output after each function declaration
pub postfix: Option<String>,
/// The way to annotation this function as #[must_use].
/// The way to annotation this function as #[must_use]
pub must_use: Option<String>,
/// The style to layout the args
pub args: Layout,
/// The rename rule to apply to function args
pub rename_args: Option<RenameRule>,
/// An optional macro to use when generating Swift function name attributes
pub swift_name_macro: Option<String>,
}
impl Default for FunctionConfig {
@@ -295,6 +297,7 @@ impl Default for FunctionConfig {
must_use: None,
args: Layout::Auto,
rename_args: None,
swift_name_macro: None,
}
}
}
+96 -7
View File
@@ -23,6 +23,9 @@ use crate::bindgen::writer::{Source, SourceWriter};
#[derive(Debug, Clone)]
pub struct Function {
pub path: Path,
/// Path to the self-type of the function
/// If the function is a method, this will contain the path of the type in the impl block
pub self_type_path: Option<Path>,
pub ret: Type,
pub args: Vec<(String, Type)>,
pub extern_decl: bool,
@@ -34,12 +37,16 @@ pub struct Function {
impl Function {
pub fn load(
path: Path,
self_type_path: Option<Path>,
sig: &syn::Signature,
extern_decl: bool,
attrs: &[syn::Attribute],
mod_cfg: Option<&Cfg>,
) -> Result<Function, String> {
let args = sig.inputs.iter().try_skip_map(|x| x.as_ident_and_type())?;
let args = sig
.inputs
.iter()
.try_skip_map(|x| x.as_ident_and_type(self_type_path.as_ref()))?;
let ret = match sig.output {
syn::ReturnType::Default => Type::Primitive(PrimitiveType::Void),
syn::ReturnType::Type(_, ref ty) => {
@@ -53,6 +60,7 @@ impl Function {
Ok(Function {
path,
self_type_path,
ret,
args,
extern_decl,
@@ -62,6 +70,35 @@ impl Function {
})
}
pub fn swift_name(&self) -> String {
// If the symbol name starts with the type name, separate the two components with '.'
// so that Swift recognises the association between the method and the type
let (ref type_prefix, ref type_name) = if let Some(type_name) = &self.self_type_path {
let type_name = type_name.to_string();
if !self.path.name().starts_with(&type_name) {
return self.path.to_string();
}
(format!("{}.", type_name), type_name)
} else {
("".to_string(), "".to_string())
};
let item_name = self
.path
.name()
.trim_start_matches(type_name)
.trim_start_matches('_');
let item_args = {
let mut items = vec![];
for (arg, _) in self.args.iter() {
items.push(format!("{}:", arg.as_str()));
}
items.join("")
};
format!("{}{}({})", type_prefix, item_name, item_args)
}
pub fn path(&self) -> &Path {
&self.path
}
@@ -160,12 +197,17 @@ impl Source for Function {
}
}
cdecl::write_func(out, &func, false, void_prototype);
if !func.extern_decl {
if let Some(ref postfix) = postfix {
out.write(" ");
write!(out, "{}", postfix);
write!(out, " {}", postfix);
}
}
if let Some(ref swift_name_macro) = config.function.swift_name_macro {
write!(out, " {}({})", swift_name_macro, func.swift_name());
}
out.write(";");
condition.write_after(config, out);
@@ -203,6 +245,11 @@ impl Source for Function {
write!(out, "{}", postfix);
}
}
if let Some(ref swift_name_macro) = config.function.swift_name_macro {
write!(out, " {}({})", swift_name_macro, func.swift_name());
}
out.write(";");
condition.write_after(config, out);
@@ -221,17 +268,46 @@ impl Source for Function {
}
pub trait SynFnArgHelpers {
fn as_ident_and_type(&self) -> Result<Option<(String, Type)>, String>;
fn as_ident_and_type(
&self,
self_type_path: Option<&Path>,
) -> Result<Option<(String, Type)>, String>;
}
fn gen_self_type(self_type_path: &Path, receiver: &syn::Receiver) -> Result<Option<Type>, String> {
fn _gen_self_type(
self_type_path: &Path,
receiver: &syn::Receiver,
) -> Result<syn::Type, syn::Error> {
Ok(match receiver.reference {
Some(_) => syn::Type::Reference(match receiver.mutability {
Some(_) => syn::parse_str(&format!("&mut {}", self_type_path))?,
None => syn::parse_str(&format!("&{}", self_type_path))?,
}),
None => syn::Type::Path(syn::parse_str(self_type_path.name())?),
})
}
Type::load(&Box::new(
_gen_self_type(self_type_path, receiver)
.map_err(|e| format!("Failed to generate self type: {}", e))?,
))
}
impl SynFnArgHelpers for syn::FnArg {
fn as_ident_and_type(&self) -> Result<Option<(String, Type)>, String> {
fn as_ident_and_type(
&self,
self_type_path: Option<&Path>,
) -> Result<Option<(String, Type)>, String> {
match self {
&syn::FnArg::Typed(syn::PatType {
ref pat, ref ty, ..
}) => match **pat {
syn::Pat::Ident(syn::PatIdent { ref ident, .. }) => {
if let Some(x) = Type::load(ty)? {
if let Some(mut x) = Type::load(ty)? {
if let Some(self_type_path) = self_type_path {
x.replace_self_with(self_type_path)
}
Ok(Some((ident.to_string(), x)))
} else {
Ok(None)
@@ -239,7 +315,20 @@ impl SynFnArgHelpers for syn::FnArg {
}
_ => Err("Parameter has an unsupported type.".to_owned()),
},
_ => Err("Parameter has an unsupported type.".to_owned()),
&syn::FnArg::Receiver(ref receiver) => {
if let Some(self_type_path) = self_type_path {
if let Some(x) = gen_self_type(self_type_path, receiver)? {
Ok(Some(("self".to_string(), x)))
} else {
Ok(None)
}
} else {
Err(
"Parameter has an unsupported type (Self type found in free function)"
.to_owned(),
)
}
}
}
}
}
+93 -40
View File
@@ -465,6 +465,24 @@ impl Parse {
if has_assoc_const {
impls_with_assoc_consts.push(item_impl);
}
if let syn::Type::Path(ref path) = *item_impl.self_ty {
if let Some(type_name) = path.path.get_ident() {
for method in item_impl.items.iter().filter_map(|item| match item {
syn::ImplItem::Method(method) => Some(method),
_ => None,
}) {
self.load_syn_method(
config,
binding_crate_name,
crate_name,
mod_cfg,
Path::new(type_name.to_string()),
method,
)
}
}
}
}
syn::Item::Macro(ref item) => {
self.load_builtin_macro(config, crate_name, mod_cfg, item)
@@ -523,7 +541,7 @@ impl Parse {
return;
}
let path = Path::new(function.sig.ident.to_string());
match Function::load(path, &function.sig, true, &function.attrs, mod_cfg) {
match Function::load(path, None, &function.sig, true, &function.attrs, mod_cfg) {
Ok(func) => {
info!("Take {}::{}.", crate_name, &function.sig.ident);
@@ -540,6 +558,29 @@ impl Parse {
}
}
/// Loads a `fn` declaration inside an `impl` block, if the type is a simple identifier
fn load_syn_method(
&mut self,
config: &Config,
binding_crate_name: &str,
crate_name: &str,
mod_cfg: Option<&Cfg>,
self_type: Path,
item: &syn::ImplItemMethod,
) {
self.load_fn_declaration(
config,
binding_crate_name,
crate_name,
mod_cfg,
item,
Some(self_type),
&item.sig,
&item.vis,
&item.attrs,
)
}
/// Loads a `fn` declaration
fn load_syn_fn(
&mut self,
@@ -548,6 +589,31 @@ impl Parse {
crate_name: &str,
mod_cfg: Option<&Cfg>,
item: &syn::ItemFn,
) {
self.load_fn_declaration(
config,
binding_crate_name,
crate_name,
mod_cfg,
item,
None,
&item.sig,
&item.vis,
&item.attrs,
);
}
fn load_fn_declaration(
&mut self,
config: &Config,
binding_crate_name: &str,
crate_name: &str,
mod_cfg: Option<&Cfg>,
named_symbol: &dyn SynItemFnHelpers,
self_type: Option<Path>,
sig: &syn::Signature,
vis: &syn::Visibility,
attrs: &[syn::Attribute],
) {
if !config
.parse
@@ -555,58 +621,45 @@ impl Parse {
{
info!(
"Skip {}::{} - (fn's outside of the binding crate are not used).",
crate_name, &item.sig.ident
crate_name, &sig.ident
);
return;
}
if let syn::Visibility::Public(_) = item.vis {
if item.sig.abi.is_omitted() || item.sig.abi.is_c() {
if let Some(exported_name) = item.exported_name() {
let path = Path::new(exported_name);
match Function::load(path, &item.sig, false, &item.attrs, mod_cfg) {
Ok(func) => {
info!("Take {}::{}.", crate_name, &item.sig.ident);
let loggable_item_name = {
let mut items = vec![];
items.push(crate_name.to_owned());
if let Some(ref self_type) = self_type {
items.push(self_type.to_string());
}
items.push(sig.ident.to_string());
items.join("::")
};
if let syn::Visibility::Public(_) = vis {
if sig.abi.is_omitted() || sig.abi.is_c() {
if let Some(exported_name) = named_symbol.exported_name() {
let path = Path::new(exported_name);
match Function::load(path, self_type, &sig, false, &attrs, mod_cfg) {
Ok(func) => {
info!("Take {}.", loggable_item_name);
self.functions.push(func);
}
Err(msg) => {
error!(
"Cannot use fn {}::{} ({}).",
crate_name, &item.sig.ident, msg
);
error!("Cannot use fn {} ({}).", loggable_item_name, msg);
}
}
return;
} else {
warn!(
"Skipping {} - (not `no_mangle`, and has no `export_name` attribute)",
loggable_item_name
);
}
} else {
warn!("Skipping {} - (not `extern \"C\"`", loggable_item_name);
}
}
// TODO
if let syn::Visibility::Public(_) = item.vis {
} else {
warn!("Skip {}::{} - (not `pub`).", crate_name, &item.sig.ident);
}
if !(item.sig.abi.is_omitted() || item.sig.abi.is_c()) {
warn!(
"Skip {}::{} - (wrong ABI - not `extern` or `extern \"C\"`).",
crate_name, &item.sig.ident
);
}
if item.exported_name().is_none() {
warn!(
"Skip {}::{} - (not `no_mangle`, and has no `export_name` attribute)",
crate_name, &item.sig.ident
);
}
if item.sig.abi.is_some() && !(item.sig.abi.is_omitted() || item.sig.abi.is_c()) {
warn!(
"Skip {}::{} - (non `extern \"C\"`).",
crate_name, &item.sig.ident
);
warn!("Skipping {} - (not `pub`)", loggable_item_name);
}
}
+15
View File
@@ -57,6 +57,20 @@ impl SynItemFnHelpers for syn::ItemFn {
}
}
impl SynItemFnHelpers for syn::ImplItemMethod {
fn exported_name(&self) -> Option<String> {
self.attrs
.attr_name_value_lookup("export_name")
.or_else(|| {
if self.is_no_mangle() {
Some(self.sig.ident.to_string())
} else {
None
}
})
}
}
pub trait SynItemHelpers {
/// Searches for attributes like `#[test]`.
/// Example:
@@ -138,6 +152,7 @@ impl_syn_item_helper!(syn::ItemUse);
impl_syn_item_helper!(syn::ItemStatic);
impl_syn_item_helper!(syn::ItemConst);
impl_syn_item_helper!(syn::ItemFn);
impl_syn_item_helper!(syn::ImplItemMethod);
impl_syn_item_helper!(syn::ItemMod);
impl_syn_item_helper!(syn::ItemForeignMod);
impl_syn_item_helper!(syn::ItemType);
+53
View File
@@ -0,0 +1,53 @@
#define CF_SWIFT_NAME(_name) __attribute__((swift_name(#_name)))
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
typedef struct Box_SelfTypeTestStruct Box_SelfTypeTestStruct;
typedef struct Opaque Opaque;
typedef struct PointerToOpaque {
Opaque *ptr;
} PointerToOpaque;
typedef struct SelfTypeTestStruct {
uint8_t times;
} SelfTypeTestStruct;
PointerToOpaque PointerToOpaque_create(uint8_t times) CF_SWIFT_NAME(PointerToOpaque.create(times:));
void PointerToOpaque_sayHello(PointerToOpaque self)
/*a comment!*/ CF_SWIFT_NAME(PointerToOpaque.sayHello(self:));
void SelfTypeTestStruct_should_exist_annotated_by_name(SelfTypeTestStruct self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_annotated_by_name(self:));
void SelfTypeTestStruct_should_exist_annotated_mut_by_name(SelfTypeTestStruct self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_annotated_mut_by_name(self:));
void SelfTypeTestStruct_should_exist_annotated_mut_self(SelfTypeTestStruct self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_annotated_mut_self(self:));
void SelfTypeTestStruct_should_exist_annotated_self(SelfTypeTestStruct self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_annotated_self(self:));
void SelfTypeTestStruct_should_exist_mut_unannotated(SelfTypeTestStruct self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_mut_unannotated(self:));
void SelfTypeTestStruct_should_exist_ref(const SelfTypeTestStruct *self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_ref(self:));
void SelfTypeTestStruct_should_exist_ref_mut(SelfTypeTestStruct *self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_ref_mut(self:));
void SelfTypeTestStruct_should_exist_unannotated(SelfTypeTestStruct self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_unannotated(self:));
void SelfTypeTestStruct_should_not_exist_box(Box_SelfTypeTestStruct self) CF_SWIFT_NAME(SelfTypeTestStruct.should_not_exist_box(self:));
void free_function_should_exist_annotated_by_name(SelfTypeTestStruct test_struct) CF_SWIFT_NAME(free_function_should_exist_annotated_by_name(test_struct:));
void free_function_should_exist_annotated_mut_by_name(SelfTypeTestStruct test_struct) CF_SWIFT_NAME(free_function_should_exist_annotated_mut_by_name(test_struct:));
void free_function_should_exist_ref(const SelfTypeTestStruct *test_struct) CF_SWIFT_NAME(free_function_should_exist_ref(test_struct:));
void free_function_should_exist_ref_mut(SelfTypeTestStruct *test_struct) CF_SWIFT_NAME(free_function_should_exist_ref_mut(test_struct:));
void free_function_should_not_exist_box(Box_SelfTypeTestStruct boxed) CF_SWIFT_NAME(free_function_should_not_exist_box(boxed:));
void rust_print_hello_world(void) CF_SWIFT_NAME(rust_print_hello_world());
@@ -0,0 +1,61 @@
#define CF_SWIFT_NAME(_name) __attribute__((swift_name(#_name)))
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
typedef struct Box_SelfTypeTestStruct Box_SelfTypeTestStruct;
typedef struct Opaque Opaque;
typedef struct PointerToOpaque {
Opaque *ptr;
} PointerToOpaque;
typedef struct SelfTypeTestStruct {
uint8_t times;
} SelfTypeTestStruct;
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
PointerToOpaque PointerToOpaque_create(uint8_t times) CF_SWIFT_NAME(PointerToOpaque.create(times:));
void PointerToOpaque_sayHello(PointerToOpaque self)
/*a comment!*/ CF_SWIFT_NAME(PointerToOpaque.sayHello(self:));
void SelfTypeTestStruct_should_exist_annotated_by_name(SelfTypeTestStruct self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_annotated_by_name(self:));
void SelfTypeTestStruct_should_exist_annotated_mut_by_name(SelfTypeTestStruct self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_annotated_mut_by_name(self:));
void SelfTypeTestStruct_should_exist_annotated_mut_self(SelfTypeTestStruct self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_annotated_mut_self(self:));
void SelfTypeTestStruct_should_exist_annotated_self(SelfTypeTestStruct self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_annotated_self(self:));
void SelfTypeTestStruct_should_exist_mut_unannotated(SelfTypeTestStruct self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_mut_unannotated(self:));
void SelfTypeTestStruct_should_exist_ref(const SelfTypeTestStruct *self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_ref(self:));
void SelfTypeTestStruct_should_exist_ref_mut(SelfTypeTestStruct *self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_ref_mut(self:));
void SelfTypeTestStruct_should_exist_unannotated(SelfTypeTestStruct self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_unannotated(self:));
void SelfTypeTestStruct_should_not_exist_box(Box_SelfTypeTestStruct self) CF_SWIFT_NAME(SelfTypeTestStruct.should_not_exist_box(self:));
void free_function_should_exist_annotated_by_name(SelfTypeTestStruct test_struct) CF_SWIFT_NAME(free_function_should_exist_annotated_by_name(test_struct:));
void free_function_should_exist_annotated_mut_by_name(SelfTypeTestStruct test_struct) CF_SWIFT_NAME(free_function_should_exist_annotated_mut_by_name(test_struct:));
void free_function_should_exist_ref(const SelfTypeTestStruct *test_struct) CF_SWIFT_NAME(free_function_should_exist_ref(test_struct:));
void free_function_should_exist_ref_mut(SelfTypeTestStruct *test_struct) CF_SWIFT_NAME(free_function_should_exist_ref_mut(test_struct:));
void free_function_should_not_exist_box(Box_SelfTypeTestStruct boxed) CF_SWIFT_NAME(free_function_should_not_exist_box(boxed:));
void rust_print_hello_world(void) CF_SWIFT_NAME(rust_print_hello_world());
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
+53
View File
@@ -0,0 +1,53 @@
#define CF_SWIFT_NAME(_name) __attribute__((swift_name(#_name)))
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
typedef struct Box_SelfTypeTestStruct Box_SelfTypeTestStruct;
typedef struct Opaque Opaque;
typedef struct {
Opaque *ptr;
} PointerToOpaque;
typedef struct {
uint8_t times;
} SelfTypeTestStruct;
PointerToOpaque PointerToOpaque_create(uint8_t times) CF_SWIFT_NAME(PointerToOpaque.create(times:));
void PointerToOpaque_sayHello(PointerToOpaque self)
/*a comment!*/ CF_SWIFT_NAME(PointerToOpaque.sayHello(self:));
void SelfTypeTestStruct_should_exist_annotated_by_name(SelfTypeTestStruct self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_annotated_by_name(self:));
void SelfTypeTestStruct_should_exist_annotated_mut_by_name(SelfTypeTestStruct self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_annotated_mut_by_name(self:));
void SelfTypeTestStruct_should_exist_annotated_mut_self(SelfTypeTestStruct self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_annotated_mut_self(self:));
void SelfTypeTestStruct_should_exist_annotated_self(SelfTypeTestStruct self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_annotated_self(self:));
void SelfTypeTestStruct_should_exist_mut_unannotated(SelfTypeTestStruct self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_mut_unannotated(self:));
void SelfTypeTestStruct_should_exist_ref(const SelfTypeTestStruct *self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_ref(self:));
void SelfTypeTestStruct_should_exist_ref_mut(SelfTypeTestStruct *self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_ref_mut(self:));
void SelfTypeTestStruct_should_exist_unannotated(SelfTypeTestStruct self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_unannotated(self:));
void SelfTypeTestStruct_should_not_exist_box(Box_SelfTypeTestStruct self) CF_SWIFT_NAME(SelfTypeTestStruct.should_not_exist_box(self:));
void free_function_should_exist_annotated_by_name(SelfTypeTestStruct test_struct) CF_SWIFT_NAME(free_function_should_exist_annotated_by_name(test_struct:));
void free_function_should_exist_annotated_mut_by_name(SelfTypeTestStruct test_struct) CF_SWIFT_NAME(free_function_should_exist_annotated_mut_by_name(test_struct:));
void free_function_should_exist_ref(const SelfTypeTestStruct *test_struct) CF_SWIFT_NAME(free_function_should_exist_ref(test_struct:));
void free_function_should_exist_ref_mut(SelfTypeTestStruct *test_struct) CF_SWIFT_NAME(free_function_should_exist_ref_mut(test_struct:));
void free_function_should_not_exist_box(Box_SelfTypeTestStruct boxed) CF_SWIFT_NAME(free_function_should_not_exist_box(boxed:));
void rust_print_hello_world(void) CF_SWIFT_NAME(rust_print_hello_world());
+61
View File
@@ -0,0 +1,61 @@
#define CF_SWIFT_NAME(_name) __attribute__((swift_name(#_name)))
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
typedef struct Box_SelfTypeTestStruct Box_SelfTypeTestStruct;
typedef struct Opaque Opaque;
typedef struct {
Opaque *ptr;
} PointerToOpaque;
typedef struct {
uint8_t times;
} SelfTypeTestStruct;
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
PointerToOpaque PointerToOpaque_create(uint8_t times) CF_SWIFT_NAME(PointerToOpaque.create(times:));
void PointerToOpaque_sayHello(PointerToOpaque self)
/*a comment!*/ CF_SWIFT_NAME(PointerToOpaque.sayHello(self:));
void SelfTypeTestStruct_should_exist_annotated_by_name(SelfTypeTestStruct self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_annotated_by_name(self:));
void SelfTypeTestStruct_should_exist_annotated_mut_by_name(SelfTypeTestStruct self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_annotated_mut_by_name(self:));
void SelfTypeTestStruct_should_exist_annotated_mut_self(SelfTypeTestStruct self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_annotated_mut_self(self:));
void SelfTypeTestStruct_should_exist_annotated_self(SelfTypeTestStruct self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_annotated_self(self:));
void SelfTypeTestStruct_should_exist_mut_unannotated(SelfTypeTestStruct self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_mut_unannotated(self:));
void SelfTypeTestStruct_should_exist_ref(const SelfTypeTestStruct *self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_ref(self:));
void SelfTypeTestStruct_should_exist_ref_mut(SelfTypeTestStruct *self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_ref_mut(self:));
void SelfTypeTestStruct_should_exist_unannotated(SelfTypeTestStruct self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_unannotated(self:));
void SelfTypeTestStruct_should_not_exist_box(Box_SelfTypeTestStruct self) CF_SWIFT_NAME(SelfTypeTestStruct.should_not_exist_box(self:));
void free_function_should_exist_annotated_by_name(SelfTypeTestStruct test_struct) CF_SWIFT_NAME(free_function_should_exist_annotated_by_name(test_struct:));
void free_function_should_exist_annotated_mut_by_name(SelfTypeTestStruct test_struct) CF_SWIFT_NAME(free_function_should_exist_annotated_mut_by_name(test_struct:));
void free_function_should_exist_ref(const SelfTypeTestStruct *test_struct) CF_SWIFT_NAME(free_function_should_exist_ref(test_struct:));
void free_function_should_exist_ref_mut(SelfTypeTestStruct *test_struct) CF_SWIFT_NAME(free_function_should_exist_ref_mut(test_struct:));
void free_function_should_not_exist_box(Box_SelfTypeTestStruct boxed) CF_SWIFT_NAME(free_function_should_not_exist_box(boxed:));
void rust_print_hello_world(void) CF_SWIFT_NAME(rust_print_hello_world());
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
+58
View File
@@ -0,0 +1,58 @@
#define CF_SWIFT_NAME(_name) __attribute__((swift_name(#_name)))
#include <cstdarg>
#include <cstdint>
#include <cstdlib>
#include <new>
template<typename T>
struct Box;
struct Opaque;
struct PointerToOpaque {
Opaque *ptr;
};
struct SelfTypeTestStruct {
uint8_t times;
};
extern "C" {
PointerToOpaque PointerToOpaque_create(uint8_t times) CF_SWIFT_NAME(PointerToOpaque.create(times:));
void PointerToOpaque_sayHello(PointerToOpaque self)
/*a comment!*/ CF_SWIFT_NAME(PointerToOpaque.sayHello(self:));
void SelfTypeTestStruct_should_exist_annotated_by_name(SelfTypeTestStruct self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_annotated_by_name(self:));
void SelfTypeTestStruct_should_exist_annotated_mut_by_name(SelfTypeTestStruct self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_annotated_mut_by_name(self:));
void SelfTypeTestStruct_should_exist_annotated_mut_self(SelfTypeTestStruct self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_annotated_mut_self(self:));
void SelfTypeTestStruct_should_exist_annotated_self(SelfTypeTestStruct self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_annotated_self(self:));
void SelfTypeTestStruct_should_exist_mut_unannotated(SelfTypeTestStruct self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_mut_unannotated(self:));
void SelfTypeTestStruct_should_exist_ref(const SelfTypeTestStruct *self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_ref(self:));
void SelfTypeTestStruct_should_exist_ref_mut(SelfTypeTestStruct *self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_ref_mut(self:));
void SelfTypeTestStruct_should_exist_unannotated(SelfTypeTestStruct self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_unannotated(self:));
void SelfTypeTestStruct_should_not_exist_box(Box<SelfTypeTestStruct> self) CF_SWIFT_NAME(SelfTypeTestStruct.should_not_exist_box(self:));
void free_function_should_exist_annotated_by_name(SelfTypeTestStruct test_struct) CF_SWIFT_NAME(free_function_should_exist_annotated_by_name(test_struct:));
void free_function_should_exist_annotated_mut_by_name(SelfTypeTestStruct test_struct) CF_SWIFT_NAME(free_function_should_exist_annotated_mut_by_name(test_struct:));
void free_function_should_exist_ref(const SelfTypeTestStruct *test_struct) CF_SWIFT_NAME(free_function_should_exist_ref(test_struct:));
void free_function_should_exist_ref_mut(SelfTypeTestStruct *test_struct) CF_SWIFT_NAME(free_function_should_exist_ref_mut(test_struct:));
void free_function_should_not_exist_box(Box<SelfTypeTestStruct> boxed) CF_SWIFT_NAME(free_function_should_not_exist_box(boxed:));
void rust_print_hello_world() CF_SWIFT_NAME(rust_print_hello_world());
} // extern "C"
+53
View File
@@ -0,0 +1,53 @@
#define CF_SWIFT_NAME(_name) __attribute__((swift_name(#_name)))
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
struct Box_SelfTypeTestStruct;
struct Opaque;
struct PointerToOpaque {
struct Opaque *ptr;
};
struct SelfTypeTestStruct {
uint8_t times;
};
struct PointerToOpaque PointerToOpaque_create(uint8_t times) CF_SWIFT_NAME(PointerToOpaque.create(times:));
void PointerToOpaque_sayHello(struct PointerToOpaque self)
/*a comment!*/ CF_SWIFT_NAME(PointerToOpaque.sayHello(self:));
void SelfTypeTestStruct_should_exist_annotated_by_name(struct SelfTypeTestStruct self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_annotated_by_name(self:));
void SelfTypeTestStruct_should_exist_annotated_mut_by_name(struct SelfTypeTestStruct self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_annotated_mut_by_name(self:));
void SelfTypeTestStruct_should_exist_annotated_mut_self(struct SelfTypeTestStruct self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_annotated_mut_self(self:));
void SelfTypeTestStruct_should_exist_annotated_self(struct SelfTypeTestStruct self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_annotated_self(self:));
void SelfTypeTestStruct_should_exist_mut_unannotated(struct SelfTypeTestStruct self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_mut_unannotated(self:));
void SelfTypeTestStruct_should_exist_ref(const struct SelfTypeTestStruct *self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_ref(self:));
void SelfTypeTestStruct_should_exist_ref_mut(struct SelfTypeTestStruct *self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_ref_mut(self:));
void SelfTypeTestStruct_should_exist_unannotated(struct SelfTypeTestStruct self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_unannotated(self:));
void SelfTypeTestStruct_should_not_exist_box(struct Box_SelfTypeTestStruct self) CF_SWIFT_NAME(SelfTypeTestStruct.should_not_exist_box(self:));
void free_function_should_exist_annotated_by_name(struct SelfTypeTestStruct test_struct) CF_SWIFT_NAME(free_function_should_exist_annotated_by_name(test_struct:));
void free_function_should_exist_annotated_mut_by_name(struct SelfTypeTestStruct test_struct) CF_SWIFT_NAME(free_function_should_exist_annotated_mut_by_name(test_struct:));
void free_function_should_exist_ref(const struct SelfTypeTestStruct *test_struct) CF_SWIFT_NAME(free_function_should_exist_ref(test_struct:));
void free_function_should_exist_ref_mut(struct SelfTypeTestStruct *test_struct) CF_SWIFT_NAME(free_function_should_exist_ref_mut(test_struct:));
void free_function_should_not_exist_box(struct Box_SelfTypeTestStruct boxed) CF_SWIFT_NAME(free_function_should_not_exist_box(boxed:));
void rust_print_hello_world(void) CF_SWIFT_NAME(rust_print_hello_world());
@@ -0,0 +1,61 @@
#define CF_SWIFT_NAME(_name) __attribute__((swift_name(#_name)))
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
struct Box_SelfTypeTestStruct;
struct Opaque;
struct PointerToOpaque {
struct Opaque *ptr;
};
struct SelfTypeTestStruct {
uint8_t times;
};
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
struct PointerToOpaque PointerToOpaque_create(uint8_t times) CF_SWIFT_NAME(PointerToOpaque.create(times:));
void PointerToOpaque_sayHello(struct PointerToOpaque self)
/*a comment!*/ CF_SWIFT_NAME(PointerToOpaque.sayHello(self:));
void SelfTypeTestStruct_should_exist_annotated_by_name(struct SelfTypeTestStruct self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_annotated_by_name(self:));
void SelfTypeTestStruct_should_exist_annotated_mut_by_name(struct SelfTypeTestStruct self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_annotated_mut_by_name(self:));
void SelfTypeTestStruct_should_exist_annotated_mut_self(struct SelfTypeTestStruct self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_annotated_mut_self(self:));
void SelfTypeTestStruct_should_exist_annotated_self(struct SelfTypeTestStruct self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_annotated_self(self:));
void SelfTypeTestStruct_should_exist_mut_unannotated(struct SelfTypeTestStruct self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_mut_unannotated(self:));
void SelfTypeTestStruct_should_exist_ref(const struct SelfTypeTestStruct *self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_ref(self:));
void SelfTypeTestStruct_should_exist_ref_mut(struct SelfTypeTestStruct *self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_ref_mut(self:));
void SelfTypeTestStruct_should_exist_unannotated(struct SelfTypeTestStruct self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_unannotated(self:));
void SelfTypeTestStruct_should_not_exist_box(struct Box_SelfTypeTestStruct self) CF_SWIFT_NAME(SelfTypeTestStruct.should_not_exist_box(self:));
void free_function_should_exist_annotated_by_name(struct SelfTypeTestStruct test_struct) CF_SWIFT_NAME(free_function_should_exist_annotated_by_name(test_struct:));
void free_function_should_exist_annotated_mut_by_name(struct SelfTypeTestStruct test_struct) CF_SWIFT_NAME(free_function_should_exist_annotated_mut_by_name(test_struct:));
void free_function_should_exist_ref(const struct SelfTypeTestStruct *test_struct) CF_SWIFT_NAME(free_function_should_exist_ref(test_struct:));
void free_function_should_exist_ref_mut(struct SelfTypeTestStruct *test_struct) CF_SWIFT_NAME(free_function_should_exist_ref_mut(test_struct:));
void free_function_should_not_exist_box(struct Box_SelfTypeTestStruct boxed) CF_SWIFT_NAME(free_function_should_not_exist_box(boxed:));
void rust_print_hello_world(void) CF_SWIFT_NAME(rust_print_hello_world());
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
+123
View File
@@ -0,0 +1,123 @@
#[export_name="rust_print_hello_world"]
pub extern fn say_hello() {
println!("Hello, World!");
}
#[repr(C)]
pub struct SelfTypeTestStruct {
times: u8,
}
impl SelfTypeTestStruct {
#[export_name="SelfTypeTestStruct_should_exist_ref"]
#[no_mangle]
pub extern fn should_exist_ref(&self) {
println!("should_exist_ref");
}
#[export_name="SelfTypeTestStruct_should_exist_ref_mut"]
#[no_mangle]
pub extern fn should_exist_ref_mut(&mut self) {
println!("should_exist_ref_mut");
}
#[export_name="SelfTypeTestStruct_should_not_exist_box"]
#[no_mangle]
pub extern fn should_not_exist_box(self: Box<SelfTypeTestStruct>) {
println!("should_not_exist_box");
}
#[export_name="SelfTypeTestStruct_should_exist_annotated_self"]
#[no_mangle]
pub extern fn should_exist_annotated_self(self: Self) {
println!("should_exist_annotated_self");
}
#[export_name="SelfTypeTestStruct_should_exist_annotated_mut_self"]
#[no_mangle]
#[allow(unused_mut)]
pub extern fn should_exist_annotated_mut_self(mut self: Self) {
println!("should_exist_annotated_mut_self");
}
#[export_name="SelfTypeTestStruct_should_exist_annotated_by_name"]
#[no_mangle]
pub extern fn should_exist_annotated_by_name(self: SelfTypeTestStruct) {
println!("should_exist_annotated_by_name");
}
#[export_name="SelfTypeTestStruct_should_exist_annotated_mut_by_name"]
#[no_mangle]
#[allow(unused_mut)]
pub extern fn should_exist_annotated_mut_by_name(mut self: SelfTypeTestStruct) {
println!("should_exist_annotated_mut_by_name");
}
#[export_name="SelfTypeTestStruct_should_exist_unannotated"]
#[no_mangle]
pub extern fn should_exist_unannotated(self) {
println!("should_exist_unannotated");
}
#[export_name="SelfTypeTestStruct_should_exist_mut_unannotated"]
#[no_mangle]
#[allow(unused_mut)]
pub extern fn should_exist_mut_unannotated(mut self) {
println!("should_exist_mut_unannotated");
}
}
#[no_mangle]
#[allow(unused_variables)]
pub extern fn free_function_should_exist_ref(test_struct: &SelfTypeTestStruct) {
println!("free_function_should_exist_ref");
}
#[no_mangle]
#[allow(unused_variables)]
pub extern fn free_function_should_exist_ref_mut(test_struct: &mut SelfTypeTestStruct) {
println!("free_function_should_exist_ref_mut");
}
#[no_mangle]
#[allow(unused_variables)]
pub extern fn free_function_should_not_exist_box(boxed: Box<SelfTypeTestStruct>) {
println!("free_function_should_not_exist_box");
}
#[no_mangle]
#[allow(unused_variables)]
pub extern fn free_function_should_exist_annotated_by_name(test_struct: SelfTypeTestStruct) {
println!("free_function_should_exist_annotated_by_name");
}
#[no_mangle]
#[allow(unused_mut)]
#[allow(unused_variables)]
pub extern fn free_function_should_exist_annotated_mut_by_name(mut test_struct: SelfTypeTestStruct) {
println!("free_function_should_exist_annotated_mut_by_name");
}
struct Opaque {
times: u8
}
#[repr(C)]
pub struct PointerToOpaque { ptr: *mut Opaque }
impl PointerToOpaque {
#[export_name="PointerToOpaque_create"]
pub extern fn create(times: u8) -> PointerToOpaque {
PointerToOpaque { ptr: Box::into_raw(Box::new(Opaque { times })) }
}
/// cbindgen:postfix=/*a comment!*/
#[export_name="PointerToOpaque_sayHello"]
pub extern fn say_hello(self: PointerToOpaque) {
if let Some(nonnull) = std::ptr::NonNull::new(self.ptr) {
for _ in 0 .. unsafe { nonnull.as_ref().times } {
println!("Hello!")
}
}
}
}
+4
View File
@@ -0,0 +1,4 @@
header = "#define CF_SWIFT_NAME(_name) __attribute__((swift_name(#_name)))"
[fn]
swift_name_macro = "CF_SWIFT_NAME"