From 85ad77bd96161f41057bd8a6e653517b8348b578 Mon Sep 17 00:00:00 2001 From: Daniel Paoliello Date: Fri, 31 Mar 2023 16:25:57 -0700 Subject: [PATCH] Add support for c_void as an opaque C++ type --- gen/src/write.rs | 3 ++- src/extern_type.rs | 2 ++ syntax/atom.rs | 3 +++ syntax/check.rs | 8 ++++---- syntax/pod.rs | 2 +- syntax/tokens.rs | 3 +++ tests/ffi/lib.rs | 2 ++ tests/ffi/tests.cc | 6 ++++++ tests/ffi/tests.h | 2 ++ tests/test.rs | 2 ++ 10 files changed, 27 insertions(+), 6 deletions(-) diff --git a/gen/src/write.rs b/gen/src/write.rs index 2acb90431..a38e65c3d 100644 --- a/gen/src/write.rs +++ b/gen/src/write.rs @@ -210,7 +210,7 @@ fn pick_includes_and_builtins(out: &mut OutFile, apis: &[Api]) { Some(Isize) => out.builtin.rust_isize = true, Some(CxxString) => out.include.string = true, Some(RustString) => out.builtin.rust_string = true, - Some(Bool | Char | F32 | F64) | None => {} + Some(Bool | Char | F32 | F64 | Cvoid) | None => {} }, Type::RustBox(_) => out.builtin.rust_box = true, Type::RustVec(_) => out.builtin.rust_vec = true, @@ -1322,6 +1322,7 @@ fn write_atom(out: &mut OutFile, atom: Atom) { F64 => write!(out, "double"), CxxString => write!(out, "::std::string"), RustString => write!(out, "::rust::String"), + Cvoid => write!(out, "void"), } } diff --git a/src/extern_type.rs b/src/extern_type.rs index d131ae127..0085f2c7b 100644 --- a/src/extern_type.rs +++ b/src/extern_type.rs @@ -2,6 +2,7 @@ use self::kind::{Kind, Opaque, Trivial}; use crate::CxxString; #[cfg(feature = "alloc")] use alloc::string::String; +use core::ffi::c_void; /// A type for which the layout is determined by its C++ definition. /// @@ -222,4 +223,5 @@ impl_extern_type! { [Opaque] CxxString = "std::string" + c_void = "void" } diff --git a/syntax/atom.rs b/syntax/atom.rs index d4ad78f17..bcd53d401 100644 --- a/syntax/atom.rs +++ b/syntax/atom.rs @@ -20,6 +20,7 @@ pub enum Atom { F64, CxxString, RustString, + Cvoid, } impl Atom { @@ -46,6 +47,7 @@ impl Atom { "f64" => Some(F64), "CxxString" => Some(CxxString), "String" => Some(RustString), + "c_void" => Some(Cvoid), _ => None, } } @@ -77,6 +79,7 @@ impl AsRef for Atom { F64 => "f64", CxxString => "CxxString", RustString => "String", + Cvoid => "c_void", } } } diff --git a/syntax/check.rs b/syntax/check.rs index b5fd45e11..c33aaa884 100644 --- a/syntax/check.rs +++ b/syntax/check.rs @@ -128,7 +128,7 @@ fn check_type_rust_vec(cx: &mut Check, ty: &Ty1) { Bool | Char | U8 | U16 | U32 | U64 | Usize | I8 | I16 | I32 | I64 | Isize | F32 | F64 | RustString, ) => return, - Some(CxxString) => {} + Some(CxxString | Cvoid) => {} } } Type::Str(_) => return, @@ -169,7 +169,7 @@ fn check_type_shared_ptr(cx: &mut Check, ptr: &Ty1) { Bool | U8 | U16 | U32 | U64 | Usize | I8 | I16 | I32 | I64 | Isize | F32 | F64 | CxxString, ) => return, - Some(Char | RustString) => {} + Some(Char | RustString | Cvoid) => {} } } else if let Type::CxxVector(_) = &ptr.inner { cx.error(ptr, "std::shared_ptr is not supported yet"); @@ -192,7 +192,7 @@ fn check_type_weak_ptr(cx: &mut Check, ptr: &Ty1) { Bool | U8 | U16 | U32 | U64 | Usize | I8 | I16 | I32 | I64 | Isize | F32 | F64 | CxxString, ) => return, - Some(Char | RustString) => {} + Some(Char | RustString | Cvoid) => {} } } else if let Type::CxxVector(_) = &ptr.inner { cx.error(ptr, "std::weak_ptr is not supported yet"); @@ -218,7 +218,7 @@ fn check_type_cxx_vector(cx: &mut Check, ptr: &Ty1) { U8 | U16 | U32 | U64 | Usize | I8 | I16 | I32 | I64 | Isize | F32 | F64 | CxxString, ) => return, Some(Char) => { /* todo */ } - Some(Bool | RustString) => {} + Some(Bool | RustString | Cvoid) => {} } } diff --git a/syntax/pod.rs b/syntax/pod.rs index 0bf152eea..30dfea524 100644 --- a/syntax/pod.rs +++ b/syntax/pod.rs @@ -10,7 +10,7 @@ impl<'a> Types<'a> { match atom { Bool | Char | U8 | U16 | U32 | U64 | Usize | I8 | I16 | I32 | I64 | Isize | F32 | F64 => true, - CxxString | RustString => false, + CxxString | RustString | Cvoid => false, } } else if let Some(strct) = self.structs.get(ident) { derive::contains(&strct.derives, Trait::Copy) diff --git a/syntax/tokens.rs b/syntax/tokens.rs index 05eddc703..6049c7bb3 100644 --- a/syntax/tokens.rs +++ b/syntax/tokens.rs @@ -20,6 +20,9 @@ impl ToTokens for Type { } else if ident.rust == RustString { let span = ident.rust.span(); tokens.extend(quote_spanned!(span=> ::cxx::alloc::string::)); + } else if ident.rust == Cvoid { + let span = ident.rust.span(); + tokens.extend(quote_spanned!(span=> ::core::ffi::)); } ident.to_tokens(tokens); } diff --git a/tests/ffi/lib.rs b/tests/ffi/lib.rs index 41ba03184..9dcd12cdf 100644 --- a/tests/ffi/lib.rs +++ b/tests/ffi/lib.rs @@ -207,6 +207,8 @@ pub mod ffi { fn c_get_use_count(weak: &WeakPtr) -> usize; + unsafe fn c_takes_void_star(value: *const c_void); + #[rust_name = "i32_overloaded_method"] fn cOverloadedMethod(&self, x: i32) -> String; #[rust_name = "str_overloaded_method"] diff --git a/tests/ffi/tests.cc b/tests/ffi/tests.cc index 8cf74bebb..a603fdb4e 100644 --- a/tests/ffi/tests.cc +++ b/tests/ffi/tests.cc @@ -598,6 +598,12 @@ size_t c_get_use_count(const std::weak_ptr &weak) noexcept { return weak.use_count(); } +void c_takes_void_star(const void *value) noexcept { + if (value == nullptr) { + cxx_test_suite_set_correct(); + } +} + extern "C" C *cxx_test_suite_get_unique_ptr() noexcept { return std::unique_ptr(new C{2020}).release(); } diff --git a/tests/ffi/tests.h b/tests/ffi/tests.h index dc02e4ff8..5dd7124bc 100644 --- a/tests/ffi/tests.h +++ b/tests/ffi/tests.h @@ -190,6 +190,8 @@ const rust::Vec &c_try_return_ref_rust_vec(const C &c); size_t c_get_use_count(const std::weak_ptr &weak) noexcept; +void c_takes_void_star(const void *value) noexcept; + void c_take_trivial_ptr(std::unique_ptr d); void c_take_trivial_ref(const D &d); void c_take_trivial_mut_ref(D &d); diff --git a/tests/test.rs b/tests/test.rs index 6ef9a8293..9d49b5315 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -362,6 +362,8 @@ fn test_extern_opaque() { let f = ffi2::c_return_ns_opaque_ptr(); check!(ffi2::c_take_opaque_ns_ref(f.as_ref().unwrap())); check!(ffi2::c_take_opaque_ns_ptr(f)); + + check!(unsafe { ffi::c_takes_void_star(core::ptr::null()) }); } #[test]