From ac3faacb35916414c7dc06e49f1377091c2c0665 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Sat, 6 Jan 2018 11:01:26 +0100 Subject: [PATCH] codegen: Be consistent about variadic signatures. Fixes #1216. --- src/codegen/mod.rs | 18 ++++---- .../tests/issue-1216-variadic-member.rs | 42 +++++++++++++++++++ tests/headers/issue-1216-variadic-member.h | 4 ++ 3 files changed, 54 insertions(+), 10 deletions(-) create mode 100644 tests/expectations/tests/issue-1216-variadic-member.rs create mode 100644 tests/headers/issue-1216-variadic-member.h diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 15885d5780..16ff79fb8c 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -3249,12 +3249,6 @@ impl CodeGenerator for Function { abi => abi, }; - let variadic = if signature.is_variadic() { - quote! { ... } - } else { - quote! {} - }; - let ident = ctx.rust_ident(canonical_name); let mut tokens = quote! { extern #abi }; tokens.append("{\n"); @@ -3262,8 +3256,6 @@ impl CodeGenerator for Function { tokens.append_separated(attributes, "\n"); tokens.append("\n"); } - let mut args = args; - args.push(variadic); tokens.append(quote! { pub fn #ident ( #( #args ),* ) #ret; }); @@ -3719,7 +3711,7 @@ mod utils { use super::ToPtr; let mut unnamed_arguments = 0; - sig.argument_types().iter().map(|&(ref name, ty)| { + let mut args = sig.argument_types().iter().map(|&(ref name, ty)| { let arg_item = ctx.resolve_item(ty); let arg_ty = arg_item.kind().expect_type(); @@ -3766,6 +3758,12 @@ mod utils { quote! { #arg_name : #arg_ty } - }).collect() + }).collect::>(); + + if sig.is_variadic() { + args.push(quote! { ... }) + } + + args } } diff --git a/tests/expectations/tests/issue-1216-variadic-member.rs b/tests/expectations/tests/issue-1216-variadic-member.rs new file mode 100644 index 0000000000..677993c042 --- /dev/null +++ b/tests/expectations/tests/issue-1216-variadic-member.rs @@ -0,0 +1,42 @@ +/* automatically generated by rust-bindgen */ + +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] + +extern "C" { + pub fn f(a: ::std::os::raw::c_int, ...); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct Foo { + pub f: ::std::option::Option< + unsafe extern "C" fn( + p: *mut ::std::os::raw::c_void, + obj: *mut ::std::os::raw::c_void, + a: ::std::os::raw::c_int, + ... + ), + >, +} +#[test] +fn bindgen_test_layout_Foo() { + assert_eq!( + ::std::mem::size_of::(), + 8usize, + concat!("Size of: ", stringify!(Foo)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(Foo)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).f as *const _ as usize }, + 0usize, + concat!("Offset of field: ", stringify!(Foo), "::", stringify!(f)) + ); +} +impl Default for Foo { + fn default() -> Self { + unsafe { ::std::mem::zeroed() } + } +} diff --git a/tests/headers/issue-1216-variadic-member.h b/tests/headers/issue-1216-variadic-member.h new file mode 100644 index 0000000000..b8bc0b81db --- /dev/null +++ b/tests/headers/issue-1216-variadic-member.h @@ -0,0 +1,4 @@ +void f(int a, ...); +struct Foo { + void (*f)(void *p, void *obj, int a, ...); +};