diff --git a/gen/src/write.rs b/gen/src/write.rs index c6d59d8b9..bd6443fc6 100644 --- a/gen/src/write.rs +++ b/gen/src/write.rs @@ -211,7 +211,9 @@ 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) | Some(Char) | Some(F32) | Some(F64) | None => {} + Some(Bool) | Some(Char) | Some(F32) | Some(F64) | Some(CInt) | Some(CLong) + | Some(CLongLong) | Some(CSChar) | Some(CShort) | Some(CUChar) | Some(CUInt) + | Some(CULong) | Some(CULongLong) | Some(CUShort) | None => {} }, Type::RustBox(_) => out.builtin.rust_box = true, Type::RustVec(_) => out.builtin.rust_vec = true, @@ -1305,6 +1307,16 @@ fn write_atom(out: &mut OutFile, atom: Atom) { F64 => write!(out, "double"), CxxString => write!(out, "::std::string"), RustString => write!(out, "::rust::String"), + CInt => write!(out, "int"), + CLong => write!(out, "long"), + CLongLong => write!(out, "long long"), + CSChar => write!(out, "signed char"), + CShort => write!(out, "short"), + CUChar => write!(out, "unsigned char"), + CUInt => write!(out, "unsigned int"), + CULong => write!(out, "unsigned long"), + CULongLong => write!(out, "unsigned long long"), + CUShort => write!(out, "unsigned short"), } } diff --git a/syntax/atom.rs b/syntax/atom.rs index d4ad78f17..44cd293e9 100644 --- a/syntax/atom.rs +++ b/syntax/atom.rs @@ -20,6 +20,16 @@ pub enum Atom { F64, CxxString, RustString, + CInt, + CLong, + CLongLong, + CSChar, + CShort, + CUChar, + CUInt, + CULong, + CULongLong, + CUShort, } impl Atom { @@ -46,6 +56,16 @@ impl Atom { "f64" => Some(F64), "CxxString" => Some(CxxString), "String" => Some(RustString), + "c_int" => Some(CInt), + "c_long" => Some(CLong), + "c_longlong" => Some(CLongLong), + "c_schar" => Some(CSChar), + "c_short" => Some(CShort), + "c_uchar" => Some(CUChar), + "c_uint" => Some(CUInt), + "c_ulong" => Some(CULong), + "c_ulonglong" => Some(CULongLong), + "c_ushort" => Some(CUShort), _ => None, } } @@ -77,6 +97,16 @@ impl AsRef for Atom { F64 => "f64", CxxString => "CxxString", RustString => "String", + CInt => "c_int", + CLong => "c_long", + CLongLong => "c_longlong", + CSChar => "c_schar", + CShort => "c_short", + CUChar => "c_uchar", + CUInt => "c_uint", + CULong => "c_ulong", + CULongLong => "c_ulonglong", + CUShort => "c_ushort", } } } diff --git a/syntax/check.rs b/syntax/check.rs index 38be4b640..1ab9332c9 100644 --- a/syntax/check.rs +++ b/syntax/check.rs @@ -125,7 +125,9 @@ fn check_type_rust_vec(cx: &mut Check, ty: &Ty1) { match Atom::from(&ident.rust) { None | Some(Char) | Some(U8) | Some(U16) | Some(U32) | Some(U64) | Some(Usize) | Some(I8) | Some(I16) | Some(I32) | Some(I64) | Some(Isize) | Some(F32) - | Some(F64) | Some(RustString) => return, + | Some(F64) | Some(RustString) | Some(CInt) | Some(CLong) | Some(CLongLong) + | Some(CSChar) | Some(CShort) | Some(CUChar) | Some(CUInt) | Some(CULong) + | Some(CULongLong) | Some(CUShort) => return, Some(Bool) => { /* todo */ } Some(CxxString) => {} } @@ -165,7 +167,9 @@ fn check_type_shared_ptr(cx: &mut Check, ptr: &Ty1) { match Atom::from(&ident.rust) { None | Some(Bool) | Some(U8) | Some(U16) | Some(U32) | Some(U64) | Some(Usize) | Some(I8) | Some(I16) | Some(I32) | Some(I64) | Some(Isize) | Some(F32) - | Some(F64) | Some(CxxString) => return, + | Some(F64) | Some(CxxString) | Some(CInt) | Some(CLong) | Some(CLongLong) + | Some(CSChar) | Some(CShort) | Some(CUChar) | Some(CUInt) | Some(CULong) + | Some(CULongLong) | Some(CUShort) => return, Some(Char) | Some(RustString) => {} } } else if let Type::CxxVector(_) = &ptr.inner { @@ -186,7 +190,9 @@ fn check_type_weak_ptr(cx: &mut Check, ptr: &Ty1) { match Atom::from(&ident.rust) { None | Some(Bool) | Some(U8) | Some(U16) | Some(U32) | Some(U64) | Some(Usize) | Some(I8) | Some(I16) | Some(I32) | Some(I64) | Some(Isize) | Some(F32) - | Some(F64) | Some(CxxString) => return, + | Some(F64) | Some(CxxString) | Some(CInt) | Some(CLong) | Some(CLongLong) + | Some(CSChar) | Some(CShort) | Some(CUChar) | Some(CUInt) | Some(CULong) + | Some(CULongLong) | Some(CUShort) => return, Some(Char) | Some(RustString) => {} } } else if let Type::CxxVector(_) = &ptr.inner { @@ -210,7 +216,9 @@ fn check_type_cxx_vector(cx: &mut Check, ptr: &Ty1) { match Atom::from(&ident.rust) { None | Some(U8) | Some(U16) | Some(U32) | Some(U64) | Some(Usize) | Some(I8) | Some(I16) | Some(I32) | Some(I64) | Some(Isize) | Some(F32) | Some(F64) - | Some(CxxString) => return, + | Some(CxxString) | Some(CInt) | Some(CLong) | Some(CLongLong) | Some(CSChar) + | Some(CShort) | Some(CUChar) | Some(CUInt) | Some(CULong) | Some(CULongLong) + | Some(CUShort) => return, Some(Char) => { /* todo */ } Some(Bool) | Some(RustString) => {} } diff --git a/syntax/pod.rs b/syntax/pod.rs index 0bf152eea..423842777 100644 --- a/syntax/pod.rs +++ b/syntax/pod.rs @@ -9,7 +9,8 @@ impl<'a> Types<'a> { if let Some(atom) = Atom::from(ident) { match atom { Bool | Char | U8 | U16 | U32 | U64 | Usize | I8 | I16 | I32 | I64 - | Isize | F32 | F64 => true, + | Isize | F32 | F64 | CInt | CLong | CLongLong | CSChar | CShort + | CUChar | CUInt | CULong | CULongLong | CUShort => true, CxxString | RustString => false, } } else if let Some(strct) = self.structs.get(ident) { diff --git a/syntax/tokens.rs b/syntax/tokens.rs index 33f20fa3c..45b197688 100644 --- a/syntax/tokens.rs +++ b/syntax/tokens.rs @@ -11,7 +11,18 @@ impl ToTokens for Type { fn to_tokens(&self, tokens: &mut TokenStream) { match self { Type::Ident(ident) => { - if ident.rust == Char { + if ident.rust == Char + || ident.rust == CInt + || ident.rust == CLong + || ident.rust == CLongLong + || ident.rust == CSChar + || ident.rust == CShort + || ident.rust == CUChar + || ident.rust == CUInt + || ident.rust == CULong + || ident.rust == CULongLong + || ident.rust == CUShort + { let span = ident.rust.span(); tokens.extend(quote_spanned!(span=> ::std::os::raw::)); } else if ident.rust == CxxString { diff --git a/tests/ffi/lib.rs b/tests/ffi/lib.rs index 25b4ccdc8..eda2fecdb 100644 --- a/tests/ffi/lib.rs +++ b/tests/ffi/lib.rs @@ -124,6 +124,18 @@ pub mod ffi { fn c_return_nested_ns_enum(n: u16) -> ABEnum; fn c_return_const_ptr(n: usize) -> *const C; fn c_return_mut_ptr(n: usize) -> *mut C; + fn c_return_char() -> c_char; + fn c_return_cint() -> c_int; + fn c_return_clong() -> c_long; + fn c_return_clonglong() -> c_longlong; + fn c_return_cschar() -> c_schar; + fn c_return_cshort() -> c_short; + fn c_return_cuchar() -> c_uchar; + fn c_return_cuint() -> c_uint; + fn c_return_culong() -> c_ulong; + fn c_return_culonglong() -> c_ulonglong; + fn c_return_cushort() -> c_ushort; + fn c_return_unique_ptr_vector_ulonglong() -> UniquePtr>; fn c_take_primitive(n: usize); fn c_take_shared(shared: Shared); diff --git a/tests/ffi/tests.cc b/tests/ffi/tests.cc index ff215ca00..58e71680b 100644 --- a/tests/ffi/tests.cc +++ b/tests/ffi/tests.cc @@ -211,6 +211,27 @@ const C *c_return_const_ptr(size_t c) { return new C(c); } C *c_return_mut_ptr(size_t c) { return new C(c); } +char c_return_char() { return 'a'; } + +int c_return_cint() { return 7; } + +long c_return_clong() { return 10; } +long long c_return_clonglong() { return 11; } +signed char c_return_cschar() { return 12; } +short c_return_cshort() { return 13; } +unsigned char c_return_cuchar() { return 14; } +unsigned int c_return_cuint() { return 15; } +unsigned long c_return_culong() { return 16; } +unsigned long long c_return_culonglong() { return 17; } +unsigned short c_return_cushort() { return 18; } + +std::unique_ptr> c_return_unique_ptr_vector_ulonglong() { + auto vec = std::unique_ptr>(new std::vector()); + vec->push_back(19); + vec->push_back(20); + return vec; +} + Borrow::Borrow(const std::string &s) : s(s) {} void Borrow::const_member() const {} diff --git a/tests/ffi/tests.h b/tests/ffi/tests.h index b624d3933..120677a00 100644 --- a/tests/ffi/tests.h +++ b/tests/ffi/tests.h @@ -120,6 +120,18 @@ ::A::B::ABEnum c_return_nested_ns_enum(uint16_t n); std::unique_ptr c_return_borrow(const std::string &s); const C *c_return_const_ptr(size_t n); C *c_return_mut_ptr(size_t n); +char c_return_char(); +int c_return_cint(); +long c_return_clong(); +long long c_return_clonglong(); +signed char c_return_cschar(); +short c_return_cshort(); +unsigned char c_return_cuchar(); +unsigned int c_return_cuint(); +unsigned long c_return_culong(); +unsigned long long c_return_culonglong(); +unsigned short c_return_cushort(); +std::unique_ptr> c_return_unique_ptr_vector_ulonglong(); void c_take_primitive(size_t n); void c_take_shared(Shared shared); diff --git a/tests/test.rs b/tests/test.rs index 1f0b16603..a7d0a38a8 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -91,6 +91,31 @@ fn test_c_return() { enm @ ffi::ABEnum::ABAVal => assert_eq!(0, enm.repr), _ => assert!(false), } + assert_eq!(ffi::c_return_char(), 'a' as i8); +} + +#[test] +#[allow(clippy::unnecessary_cast)] // because we want explicitly + // to check that these types match the various std::os::raw + // types, even when those types are actually just + // aliases for i32, etc. +fn test_c_return_raw_types() { + assert_eq!(ffi::c_return_cint(), 7 as std::os::raw::c_int); + assert_eq!(ffi::c_return_clong(), 10 as std::os::raw::c_long); + assert_eq!(ffi::c_return_clonglong(), 11 as std::os::raw::c_longlong); + assert_eq!(ffi::c_return_cschar(), 12 as std::os::raw::c_schar); + assert_eq!(ffi::c_return_cshort(), 13 as std::os::raw::c_short); + assert_eq!(ffi::c_return_cuchar(), 14 as std::os::raw::c_uchar); + assert_eq!(ffi::c_return_cuint(), 15 as std::os::raw::c_uint); + assert_eq!(ffi::c_return_culong(), 16 as std::os::raw::c_ulong); + assert_eq!(ffi::c_return_culonglong(), 17 as std::os::raw::c_ulonglong); + assert_eq!(ffi::c_return_cushort(), 18 as std::os::raw::c_ushort); + assert_eq!( + 39 as std::os::raw::c_ulonglong, + ffi::c_return_unique_ptr_vector_ulonglong() + .into_iter() + .sum(), + ); } #[test]