diff --git a/src/bindgen/utilities.rs b/src/bindgen/utilities.rs index 28ae7838..f4058313 100644 --- a/src/bindgen/utilities.rs +++ b/src/bindgen/utilities.rs @@ -50,6 +50,7 @@ impl SynItemHelpers for syn::ImplItemFn { fn exported_name(&self) -> Option { self.attrs .attr_name_value_lookup("export_name") + .or_else(|| self.unsafe_attr_name_value_lookup("export_name")) .or_else(|| { if self.is_no_mangle() { Some(self.sig.ident.unraw().to_string()) diff --git a/tests/expectations-symbols/impl_unsafe_attr_method.c.sym b/tests/expectations-symbols/impl_unsafe_attr_method.c.sym new file mode 100644 index 00000000..271f7251 --- /dev/null +++ b/tests/expectations-symbols/impl_unsafe_attr_method.c.sym @@ -0,0 +1,4 @@ +{ +new_dummy; +new_dummy_param; +}; \ No newline at end of file diff --git a/tests/expectations/impl_unsafe_attr_method.c b/tests/expectations/impl_unsafe_attr_method.c new file mode 100644 index 00000000..822c4cea --- /dev/null +++ b/tests/expectations/impl_unsafe_attr_method.c @@ -0,0 +1,12 @@ +#include +#include +#include +#include + +typedef struct { + int32_t dummy_field; +} DummyStruct; + +DummyStruct new_dummy(void); + +DummyStruct new_dummy_param(int32_t dummy_field); diff --git a/tests/expectations/impl_unsafe_attr_method.compat.c b/tests/expectations/impl_unsafe_attr_method.compat.c new file mode 100644 index 00000000..a4752756 --- /dev/null +++ b/tests/expectations/impl_unsafe_attr_method.compat.c @@ -0,0 +1,20 @@ +#include +#include +#include +#include + +typedef struct { + int32_t dummy_field; +} DummyStruct; + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +DummyStruct new_dummy(void); + +DummyStruct new_dummy_param(int32_t dummy_field); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus diff --git a/tests/expectations/impl_unsafe_attr_method.cpp b/tests/expectations/impl_unsafe_attr_method.cpp new file mode 100644 index 00000000..1f12ee89 --- /dev/null +++ b/tests/expectations/impl_unsafe_attr_method.cpp @@ -0,0 +1,17 @@ +#include +#include +#include +#include +#include + +struct DummyStruct { + int32_t dummy_field; +}; + +extern "C" { + +DummyStruct new_dummy(); + +DummyStruct new_dummy_param(int32_t dummy_field); + +} // extern "C" diff --git a/tests/expectations/impl_unsafe_attr_method.pyx b/tests/expectations/impl_unsafe_attr_method.pyx new file mode 100644 index 00000000..c502b519 --- /dev/null +++ b/tests/expectations/impl_unsafe_attr_method.pyx @@ -0,0 +1,14 @@ +from libc.stdint cimport int8_t, int16_t, int32_t, int64_t, intptr_t +from libc.stdint cimport uint8_t, uint16_t, uint32_t, uint64_t, uintptr_t +cdef extern from *: + ctypedef bint bool + ctypedef struct va_list + +cdef extern from *: + + ctypedef struct DummyStruct: + int32_t dummy_field; + + DummyStruct new_dummy(); + + DummyStruct new_dummy_param(int32_t dummy_field); diff --git a/tests/expectations/impl_unsafe_attr_method_both.c b/tests/expectations/impl_unsafe_attr_method_both.c new file mode 100644 index 00000000..9c6a0d7d --- /dev/null +++ b/tests/expectations/impl_unsafe_attr_method_both.c @@ -0,0 +1,12 @@ +#include +#include +#include +#include + +typedef struct DummyStruct { + int32_t dummy_field; +} DummyStruct; + +struct DummyStruct new_dummy(void); + +struct DummyStruct new_dummy_param(int32_t dummy_field); diff --git a/tests/expectations/impl_unsafe_attr_method_both.compat.c b/tests/expectations/impl_unsafe_attr_method_both.compat.c new file mode 100644 index 00000000..c933e17d --- /dev/null +++ b/tests/expectations/impl_unsafe_attr_method_both.compat.c @@ -0,0 +1,20 @@ +#include +#include +#include +#include + +typedef struct DummyStruct { + int32_t dummy_field; +} DummyStruct; + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +struct DummyStruct new_dummy(void); + +struct DummyStruct new_dummy_param(int32_t dummy_field); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus diff --git a/tests/expectations/impl_unsafe_attr_method_tag.c b/tests/expectations/impl_unsafe_attr_method_tag.c new file mode 100644 index 00000000..d0db9853 --- /dev/null +++ b/tests/expectations/impl_unsafe_attr_method_tag.c @@ -0,0 +1,12 @@ +#include +#include +#include +#include + +struct DummyStruct { + int32_t dummy_field; +}; + +struct DummyStruct new_dummy(void); + +struct DummyStruct new_dummy_param(int32_t dummy_field); diff --git a/tests/expectations/impl_unsafe_attr_method_tag.compat.c b/tests/expectations/impl_unsafe_attr_method_tag.compat.c new file mode 100644 index 00000000..40e53fa8 --- /dev/null +++ b/tests/expectations/impl_unsafe_attr_method_tag.compat.c @@ -0,0 +1,20 @@ +#include +#include +#include +#include + +struct DummyStruct { + int32_t dummy_field; +}; + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +struct DummyStruct new_dummy(void); + +struct DummyStruct new_dummy_param(int32_t dummy_field); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus diff --git a/tests/expectations/impl_unsafe_attr_method_tag.pyx b/tests/expectations/impl_unsafe_attr_method_tag.pyx new file mode 100644 index 00000000..23c9f172 --- /dev/null +++ b/tests/expectations/impl_unsafe_attr_method_tag.pyx @@ -0,0 +1,14 @@ +from libc.stdint cimport int8_t, int16_t, int32_t, int64_t, intptr_t +from libc.stdint cimport uint8_t, uint16_t, uint32_t, uint64_t, uintptr_t +cdef extern from *: + ctypedef bint bool + ctypedef struct va_list + +cdef extern from *: + + cdef struct DummyStruct: + int32_t dummy_field; + + DummyStruct new_dummy(); + + DummyStruct new_dummy_param(int32_t dummy_field); diff --git a/tests/rust/impl_unsafe_attr_method.rs b/tests/rust/impl_unsafe_attr_method.rs new file mode 100644 index 00000000..4f604bfb --- /dev/null +++ b/tests/rust/impl_unsafe_attr_method.rs @@ -0,0 +1,21 @@ +#[repr(C)] +pub struct DummyStruct { + dummy_field: i32, +} + + +impl DummyStruct { + #[unsafe(export_name = "new_dummy")] + pub const extern "C" fn new() -> Self { + Self { + dummy_field: 0, + } + } + + #[unsafe(no_mangle)] + pub extern "C" fn new_dummy_param(dummy_field: i32) -> Self { + Self { + dummy_field, + } + } +}