Skip to content
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

Adds custom_const_pointer_type and custom_mut_pointer_type options. #2708

Open
wants to merge 1 commit into
base: main
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
26 changes: 26 additions & 0 deletions bindgen/codegen/helpers.rs
Expand Up @@ -352,4 +352,30 @@
})
.collect()
}

pub(crate) fn to_ptr(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a quick doc since ToPtr (which had them) was removed?

ctx: &BindgenContext,
ty: syn::Type,
is_const: bool,
) -> syn::Type {
if is_const {
if let Some(wrapper) =
ctx.options().custom_const_pointer_type.as_ref()
{
let wrapper = ctx.rust_ident_raw(wrapper);
syn::parse_quote! { #wrapper<#ty> }
} else {
syn::parse_quote! { *const #ty }
}
} else {

Check warning on line 370 in bindgen/codegen/helpers.rs

View workflow job for this annotation

GitHub Actions / rustfmt-clippy

this `else { if .. }` block can be collapsed
if let Some(wrapper) =
ctx.options().custom_mut_pointer_type.as_ref()
{
let wrapper = ctx.rust_ident_raw(wrapper);
syn::parse_quote! { #wrapper<#ty> }
} else {
syn::parse_quote! { *mut #ty }
}
}
emilio marked this conversation as resolved.
Show resolved Hide resolved
}
}
38 changes: 13 additions & 25 deletions bindgen/codegen/mod.rs
Expand Up @@ -15,7 +15,9 @@ pub(crate) mod bitfield_unit;
mod bitfield_unit_tests;

use self::dyngen::DynamicItems;
use self::helpers::ast_ty::to_ptr;
use self::helpers::attributes;

use self::struct_layout::StructLayoutTracker;

use super::BindgenOptions;
Expand Down Expand Up @@ -390,22 +392,6 @@ impl<'a> ops::DerefMut for CodegenResult<'a> {
}
}

/// A trait to convert a rust type into a pointer, optionally const, to the same
/// type.
trait ToPtr {
fn to_ptr(self, is_const: bool) -> syn::Type;
}

impl ToPtr for syn::Type {
fn to_ptr(self, is_const: bool) -> syn::Type {
if is_const {
syn::parse_quote! { *const #self }
} else {
syn::parse_quote! { *mut #self }
}
}
}

/// An extension trait for `syn::Type` that lets us append any implicit
/// template parameters that exist for some type, if necessary.
trait WithImplicitTemplateParams {
Expand Down Expand Up @@ -1984,10 +1970,10 @@ impl CodeGenerator for CompInfo {
let vtable = Vtable::new(item.id(), self);
vtable.codegen(ctx, result, item);

let vtable_type = vtable
let vtable_item_type = vtable
.try_to_rust_ty(ctx, &())
.expect("vtable to Rust type conversion is infallible")
.to_ptr(true);
.expect("vtable to Rust type conversion is infallible");
let vtable_type = to_ptr(ctx, vtable_item_type, true);

fields.push(quote! {
pub vtable_: #vtable_type ,
Expand Down Expand Up @@ -3850,7 +3836,7 @@ impl TryToRustTy for Type {
TypeKind::Void => Ok(c_void(ctx)),
// TODO: we should do something smart with nullptr, or maybe *const
// c_void is enough?
TypeKind::NullPtr => Ok(c_void(ctx).to_ptr(true)),
TypeKind::NullPtr => Ok(to_ptr(ctx, c_void(ctx), true)),
TypeKind::Int(ik) => {
Ok(int_kind_rust_type(ctx, ik, self.layout(ctx)))
}
Expand Down Expand Up @@ -3897,7 +3883,7 @@ impl TryToRustTy for Type {
TypeKind::BlockPointer(..) => {
if self.is_block_pointer() && !ctx.options().generate_block {
let void = c_void(ctx);
return Ok(void.to_ptr(/* is_const = */ false));
return Ok(to_ptr(ctx, void, /* is_const = */ false));
}

if item.is_opaque(ctx, &()) &&
Expand Down Expand Up @@ -3959,7 +3945,7 @@ impl TryToRustTy for Type {
{
Ok(ty)
} else {
Ok(ty.to_ptr(is_const))
Ok(to_ptr(ctx, ty, is_const))
}
}
TypeKind::TypeParam => {
Expand Down Expand Up @@ -5257,8 +5243,6 @@ pub(crate) mod utils {
ctx: &BindgenContext,
ty: &TypeId,
) -> syn::Type {
use super::ToPtr;

let arg_item = ctx.resolve_item(ty);
let arg_ty = arg_item.kind().expect_type();

Expand All @@ -5277,7 +5261,11 @@ pub(crate) mod utils {
} else {
t.to_rust_ty_or_opaque(ctx, &())
};
stream.to_ptr(ctx.resolve_type(t).is_const())
super::helpers::ast_ty::to_ptr(
ctx,
stream,
ctx.resolve_type(t).is_const(),
)
}
TypeKind::Pointer(inner) => {
let inner = ctx.resolve_item(inner);
Expand Down
22 changes: 22 additions & 0 deletions bindgen/options/mod.rs
Expand Up @@ -2059,5 +2059,27 @@ options! {
}
},
as_args: "--emit-diagnostics",
},
/// A type to use for const pointers.
custom_const_pointer_type: Option<String> {
methods: {
/// Sets the given type to be used instead of const pointers.
pub fn custom_const_pointer_type<T: Into<String>>(mut self, custom_const_pointer_type: Option<T>) -> Self {
self.options.custom_const_pointer_type = custom_const_pointer_type.map(|s| s.into());
self
}
},
as_args: "--custom-const-pointer-type",
},
/// A type to use for mut pointers.
custom_mut_pointer_type: Option<String> {
methods: {
/// Sets the given type to be used instead of mut pointers.
pub fn custom_mut_pointer_type<T: Into<String>>(mut self, custom_mut_pointer_type: Option<T>) -> Self {
self.options.custom_mut_pointer_type = custom_mut_pointer_type.map(|s| s.into());
self
}
},
as_args: "--custom-mut-pointer-type",
}
}