Skip to content

Support standard C numeric types #874

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion gen/src/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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"),
}
}

Expand Down
30 changes: 30 additions & 0 deletions syntax/atom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,16 @@ pub enum Atom {
F64,
CxxString,
RustString,
CInt,
CLong,
CLongLong,
CSChar,
CShort,
CUChar,
CUInt,
CULong,
CULongLong,
CUShort,
}

impl Atom {
Expand All @@ -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,
}
}
Expand Down Expand Up @@ -77,6 +97,16 @@ impl AsRef<str> 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",
}
}
}
Expand Down
16 changes: 12 additions & 4 deletions syntax/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) => {}
}
Expand Down Expand Up @@ -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 {
Expand All @@ -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 {
Expand All @@ -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) => {}
}
Expand Down
3 changes: 2 additions & 1 deletion syntax/pod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
13 changes: 12 additions & 1 deletion syntax/tokens.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
12 changes: 12 additions & 0 deletions tests/ffi/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<CxxVector<c_ulonglong>>;

fn c_take_primitive(n: usize);
fn c_take_shared(shared: Shared);
Expand Down
21 changes: 21 additions & 0 deletions tests/ffi/tests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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<std::vector<unsigned long long>> c_return_unique_ptr_vector_ulonglong() {
auto vec = std::unique_ptr<std::vector<unsigned long long>>(new std::vector<unsigned long long>());
vec->push_back(19);
vec->push_back(20);
return vec;
}

Borrow::Borrow(const std::string &s) : s(s) {}

void Borrow::const_member() const {}
Expand Down
12 changes: 12 additions & 0 deletions tests/ffi/tests.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,18 @@ ::A::B::ABEnum c_return_nested_ns_enum(uint16_t n);
std::unique_ptr<Borrow> 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<std::vector<unsigned long long>> c_return_unique_ptr_vector_ulonglong();

void c_take_primitive(size_t n);
void c_take_shared(Shared shared);
Expand Down
25 changes: 25 additions & 0 deletions tests/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down