diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 5ce42c3449..ffb21d13b3 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -1045,7 +1045,8 @@ impl<'a> CodeGenerator for Vtable<'a> { // For now, we will only generate vtables for classes that: // - do not inherit from others (compilers merge VTable from primary parent class). // - do not contain a virtual destructor (requires ordering; platforms generate different vtables). - if self.comp_info.base_members().is_empty() && + if ctx.options().vtable_generation && + self.comp_info.base_members().is_empty() && self.comp_info.destructor().is_none() { let class_ident = ctx.rust_ident(self.item_id.canonical_name(ctx)); @@ -1076,9 +1077,9 @@ impl<'a> CodeGenerator for Vtable<'a> { let ret = utils::fnsig_return_ty(ctx, signature); args[0] = if m.is_const() { - quote! { this: & #class_ident } + quote! { this: *const #class_ident } } else { - quote! { this: &mut #class_ident } + quote! { this: *mut #class_ident } }; Some(quote! { @@ -1793,7 +1794,7 @@ impl CodeGenerator for CompInfo { if !is_opaque { if item.has_vtable_ptr(ctx) { - let vtable = Vtable::new(item.id(), &self); + let vtable = Vtable::new(item.id(), self); vtable.codegen(ctx, result, item); let vtable_type = vtable diff --git a/src/lib.rs b/src/lib.rs index ea5c61b405..baea21b7e0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -569,6 +569,10 @@ impl Builder { output_vector.push("--explicit-padding".into()); } + if self.options.vtable_generation { + output_vector.push("--vtable-generation".into()); + } + // Add clang arguments output_vector.push("--".into()); @@ -1450,6 +1454,14 @@ impl Builder { self } + /// If true, enables experimental support to generate vtable functions. + /// + /// Should mostly work, though some edge cases are likely to be broken. + pub fn vtable_generation(mut self, doit: bool) -> Self { + self.options.vtable_generation = doit; + self + } + /// Generate the Rust bindings using the options built up thus far. pub fn generate(mut self) -> Result { // Add any extra arguments from the environment to the clang command line. @@ -1981,6 +1993,9 @@ struct BindgenOptions { /// Always output explicit padding fields force_explicit_padding: bool, + + /// Emit vtable functions. + vtable_generation: bool, } /// TODO(emilio): This is sort of a lie (see the error message that results from @@ -2128,6 +2143,7 @@ impl Default for BindgenOptions { translate_enum_integer_types: false, c_naming: false, force_explicit_padding: false, + vtable_generation: false, } } } diff --git a/src/options.rs b/src/options.rs index 04d42ed5c3..081aad61da 100644 --- a/src/options.rs +++ b/src/options.rs @@ -542,6 +542,9 @@ where Arg::new("explicit-padding") .long("explicit-padding") .help("Always output explicit padding fields."), + Arg::new("vtable-generation") + .long("vtable-generation") + .help("Enables generation of vtable functions."), ]) // .args() .get_matches_from(args); @@ -1008,6 +1011,10 @@ where builder = builder.explicit_padding(true); } + if matches.is_present("vtable-generation") { + builder = builder.vtable_generation(true); + } + let verbose = matches.is_present("verbose"); Ok((builder, output, verbose)) diff --git a/tests/expectations/tests/enum_and_vtable_mangling.rs b/tests/expectations/tests/enum_and_vtable_mangling.rs index bd6f7ff603..5ae76c4c29 100644 --- a/tests/expectations/tests/enum_and_vtable_mangling.rs +++ b/tests/expectations/tests/enum_and_vtable_mangling.rs @@ -15,7 +15,7 @@ pub enum _bindgen_ty_1 { } #[repr(C)] pub struct C__bindgen_vtable { - pub C_match: unsafe extern "C" fn(this: &mut C), + pub C_match: unsafe extern "C" fn(this: *mut C), } #[repr(C)] #[derive(Debug, Copy, Clone)] diff --git a/tests/expectations/tests/nested_vtable.rs b/tests/expectations/tests/nested_vtable.rs index 8747a59f11..7ee483044e 100644 --- a/tests/expectations/tests/nested_vtable.rs +++ b/tests/expectations/tests/nested_vtable.rs @@ -8,7 +8,7 @@ #[repr(C)] pub struct nsISupports__bindgen_vtable { pub nsISupports_QueryInterface: - unsafe extern "C" fn(this: &mut nsISupports) -> *mut nsISupports, + unsafe extern "C" fn(this: *mut nsISupports) -> *mut nsISupports, } #[repr(C)] #[derive(Debug, Copy, Clone)] diff --git a/tests/expectations/tests/ref_argument_array.rs b/tests/expectations/tests/ref_argument_array.rs index a99bf2c3bf..00a8e0ee35 100644 --- a/tests/expectations/tests/ref_argument_array.rs +++ b/tests/expectations/tests/ref_argument_array.rs @@ -9,7 +9,7 @@ pub const NSID_LENGTH: u32 = 10; #[repr(C)] pub struct nsID__bindgen_vtable { pub nsID_ToProvidedString: unsafe extern "C" fn( - this: &mut nsID, + this: *mut nsID, aDest: *mut [::std::os::raw::c_char; 10usize], ), } diff --git a/tests/expectations/tests/virtual_interface.rs b/tests/expectations/tests/virtual_interface.rs index 7677c51fb6..be94f23205 100644 --- a/tests/expectations/tests/virtual_interface.rs +++ b/tests/expectations/tests/virtual_interface.rs @@ -7,9 +7,9 @@ #[repr(C)] pub struct PureVirtualIFace__bindgen_vtable { - pub PureVirtualIFace_Foo: unsafe extern "C" fn(this: &mut PureVirtualIFace), + pub PureVirtualIFace_Foo: unsafe extern "C" fn(this: *mut PureVirtualIFace), pub PureVirtualIFace_Bar: unsafe extern "C" fn( - this: &mut PureVirtualIFace, + this: *mut PureVirtualIFace, arg1: ::std::os::raw::c_uint, ), } @@ -42,7 +42,7 @@ impl Default for PureVirtualIFace { } #[repr(C)] pub struct AnotherInterface__bindgen_vtable { - pub AnotherInterface_Baz: unsafe extern "C" fn(this: &mut AnotherInterface), + pub AnotherInterface_Baz: unsafe extern "C" fn(this: *mut AnotherInterface), } #[repr(C)] #[derive(Debug, Copy, Clone)] diff --git a/tests/expectations/tests/virtual_overloaded.rs b/tests/expectations/tests/virtual_overloaded.rs index 3fcfe33e61..c117d9ef6c 100644 --- a/tests/expectations/tests/virtual_overloaded.rs +++ b/tests/expectations/tests/virtual_overloaded.rs @@ -8,9 +8,9 @@ #[repr(C)] pub struct C__bindgen_vtable { pub C_do_thing: - unsafe extern "C" fn(this: &mut C, arg1: ::std::os::raw::c_char), + unsafe extern "C" fn(this: *mut C, arg1: ::std::os::raw::c_char), pub C_do_thing1: - unsafe extern "C" fn(this: &mut C, arg1: ::std::os::raw::c_int), + unsafe extern "C" fn(this: *mut C, arg1: ::std::os::raw::c_int), } #[repr(C)] #[derive(Debug, Copy, Clone)] diff --git a/tests/expectations/tests/vtable_recursive_sig.rs b/tests/expectations/tests/vtable_recursive_sig.rs index dd1b0f4d16..74e1dc7914 100644 --- a/tests/expectations/tests/vtable_recursive_sig.rs +++ b/tests/expectations/tests/vtable_recursive_sig.rs @@ -7,7 +7,7 @@ #[repr(C)] pub struct Base__bindgen_vtable { - pub Base_AsDerived: unsafe extern "C" fn(this: &mut Base) -> *mut Derived, + pub Base_AsDerived: unsafe extern "C" fn(this: *mut Base) -> *mut Derived, } #[repr(C)] #[derive(Debug, Copy, Clone)] diff --git a/tests/tests.rs b/tests/tests.rs index 274c568301..1f116c93b3 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -365,6 +365,7 @@ fn create_bindgen_builder(header: &Path) -> Result { "--no-rustfmt-bindings", "--with-derive-default", "--disable-header-comment", + "--vtable-generation", header_str, "--raw-line", "",