generator: Turn c_void-returning functions into Rust () (#362)
`c_void` is not the same as Rust's void type, `()`, making function pointers like `PFN_vkFreeFunction` pretty much impossible to implement without casting. Instead of just turning this into `-> ()`, remove the return type altogether, and add some asserts to prevent types of this kind from being accidentally generated.
This commit is contained in:
parent
dd2849450f
commit
e8b369db7d
|
@ -383,7 +383,7 @@ pub type PFN_vkInternalAllocationNotification = Option<
|
|||
size: usize,
|
||||
allocation_type: InternalAllocationType,
|
||||
allocation_scope: SystemAllocationScope,
|
||||
) -> c_void,
|
||||
),
|
||||
>;
|
||||
#[allow(non_camel_case_types)]
|
||||
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/PFN_vkInternalFreeNotification.html>"]
|
||||
|
@ -393,7 +393,7 @@ pub type PFN_vkInternalFreeNotification = Option<
|
|||
size: usize,
|
||||
allocation_type: InternalAllocationType,
|
||||
allocation_scope: SystemAllocationScope,
|
||||
) -> c_void,
|
||||
),
|
||||
>;
|
||||
#[allow(non_camel_case_types)]
|
||||
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/PFN_vkReallocationFunction.html>"]
|
||||
|
@ -419,10 +419,10 @@ pub type PFN_vkAllocationFunction = Option<
|
|||
#[allow(non_camel_case_types)]
|
||||
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/PFN_vkFreeFunction.html>"]
|
||||
pub type PFN_vkFreeFunction =
|
||||
Option<unsafe extern "system" fn(p_user_data: *mut c_void, p_memory: *mut c_void) -> c_void>;
|
||||
Option<unsafe extern "system" fn(p_user_data: *mut c_void, p_memory: *mut c_void)>;
|
||||
#[allow(non_camel_case_types)]
|
||||
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/PFN_vkVoidFunction.html>"]
|
||||
pub type PFN_vkVoidFunction = Option<unsafe extern "system" fn() -> c_void>;
|
||||
pub type PFN_vkVoidFunction = Option<unsafe extern "system" fn()>;
|
||||
#[allow(non_camel_case_types)]
|
||||
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/PFN_vkDebugReportCallbackEXT.html>"]
|
||||
pub type PFN_vkDebugReportCallbackEXT = Option<
|
||||
|
@ -453,7 +453,7 @@ pub type PFN_vkDeviceMemoryReportCallbackEXT = Option<
|
|||
unsafe extern "system" fn(
|
||||
p_callback_data: *const DeviceMemoryReportCallbackDataEXT,
|
||||
p_user_data: *mut c_void,
|
||||
) -> c_void,
|
||||
),
|
||||
>;
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -623,6 +623,9 @@ pub trait FieldExt {
|
|||
/// which is needed for `C` function parameters. Set to `false` for struct definitions.
|
||||
fn type_tokens(&self, is_ffi_param: bool) -> TokenStream;
|
||||
fn is_clone(&self) -> bool;
|
||||
|
||||
/// Whether this is C's `void` type (not to be mistaken with a void _pointer_!)
|
||||
fn is_void(&self) -> bool;
|
||||
}
|
||||
|
||||
pub trait ToTokens {
|
||||
|
@ -729,6 +732,7 @@ impl FieldExt for vkxml::Field {
|
|||
}
|
||||
|
||||
fn inner_type_tokens(&self) -> TokenStream {
|
||||
assert!(!self.is_void());
|
||||
let ty = name_to_tokens(&self.basetype);
|
||||
|
||||
match self.reference {
|
||||
|
@ -739,6 +743,7 @@ impl FieldExt for vkxml::Field {
|
|||
}
|
||||
|
||||
fn safe_type_tokens(&self, lifetime: TokenStream) -> TokenStream {
|
||||
assert!(!self.is_void());
|
||||
match self.array {
|
||||
// The outer type fn type_tokens() returns is [], which fits our "safe" prescription
|
||||
Some(vkxml::ArrayType::Static) => self.type_tokens(false),
|
||||
|
@ -758,6 +763,7 @@ impl FieldExt for vkxml::Field {
|
|||
}
|
||||
|
||||
fn type_tokens(&self, is_ffi_param: bool) -> TokenStream {
|
||||
assert!(!self.is_void());
|
||||
let ty = name_to_tokens(&self.basetype);
|
||||
|
||||
match self.array {
|
||||
|
@ -784,6 +790,10 @@ impl FieldExt for vkxml::Field {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn is_void(&self) -> bool {
|
||||
self.basetype == "void" && self.reference.is_none()
|
||||
}
|
||||
}
|
||||
|
||||
pub type CommandMap<'a> = HashMap<vkxml::Identifier, &'a vkxml::Command>;
|
||||
|
@ -901,12 +911,6 @@ fn generate_function_pointers<'a>(
|
|||
.collect();
|
||||
let expanded_params_ref = &expanded_params;
|
||||
|
||||
let return_types: Vec<_> = commands
|
||||
.iter()
|
||||
.map(|cmd| cmd.return_type.type_tokens(true))
|
||||
.collect();
|
||||
let return_types_ref = &return_types;
|
||||
|
||||
let pfn_names: Vec<_> = commands_pfn
|
||||
.iter()
|
||||
.map(|cmd| format_ident!("{}", format!("PFN_{}", cmd.name.as_str())))
|
||||
|
@ -930,21 +934,28 @@ fn generate_function_pointers<'a>(
|
|||
.collect();
|
||||
let signature_params_ref = &signature_params;
|
||||
|
||||
let pfn_return_types: Vec<_> = commands
|
||||
let return_types: Vec<_> = commands
|
||||
.iter()
|
||||
.map(|cmd| cmd.return_type.type_tokens(true))
|
||||
.map(|cmd| {
|
||||
if cmd.return_type.is_void() {
|
||||
quote!()
|
||||
} else {
|
||||
let ret_ty_tokens = cmd.return_type.type_tokens(true);
|
||||
quote!(-> #ret_ty_tokens)
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
let pfn_return_types_ref = &pfn_return_types;
|
||||
let return_types_ref = &return_types;
|
||||
|
||||
quote! {
|
||||
#(
|
||||
#[allow(non_camel_case_types)]
|
||||
pub type #pfn_names_ref = extern "system" fn(#(#signature_params_ref),*) -> #pfn_return_types_ref;
|
||||
pub type #pfn_names_ref = extern "system" fn(#(#signature_params_ref),*) #return_types_ref;
|
||||
)*
|
||||
|
||||
pub struct #ident {
|
||||
#(
|
||||
pub #names_ref: extern "system" fn(#expanded_params_ref) -> #return_types_ref,
|
||||
pub #names_ref: extern "system" fn(#expanded_params_ref) #return_types_ref,
|
||||
)*
|
||||
}
|
||||
|
||||
|
@ -966,7 +977,7 @@ fn generate_function_pointers<'a>(
|
|||
#(
|
||||
#names_ref: unsafe {
|
||||
|
||||
extern "system" fn #names_ref1 (#expanded_params_unused) -> #return_types_ref {
|
||||
extern "system" fn #names_ref1 (#expanded_params_unused) #return_types_ref {
|
||||
panic!(concat!("Unable to load ", stringify!(#names_ref2)))
|
||||
}
|
||||
let raw_name = stringify!(#raw_names_ref);
|
||||
|
@ -984,7 +995,7 @@ fn generate_function_pointers<'a>(
|
|||
}
|
||||
#(
|
||||
#[doc = #khronos_links]
|
||||
pub unsafe fn #names_ref(&self, #expanded_params_ref) -> #return_types_ref {
|
||||
pub unsafe fn #names_ref(&self, #expanded_params_ref) #return_types_ref {
|
||||
(self.#names_left)(#(#params_names,)*)
|
||||
}
|
||||
)*
|
||||
|
@ -2060,7 +2071,12 @@ pub fn generate_handle(handle: &vkxml::Handle) -> Option<TokenStream> {
|
|||
}
|
||||
fn generate_funcptr(fnptr: &vkxml::FunctionPointer) -> TokenStream {
|
||||
let name = format_ident!("{}", fnptr.name.as_str());
|
||||
let ret_ty_tokens = fnptr.return_type.type_tokens(true);
|
||||
let ret_ty_tokens = if fnptr.return_type.is_void() {
|
||||
quote!()
|
||||
} else {
|
||||
let ret_ty_tokens = fnptr.return_type.type_tokens(true);
|
||||
quote!(-> #ret_ty_tokens)
|
||||
};
|
||||
let params = fnptr.param.iter().map(|field| {
|
||||
let ident = field.param_ident();
|
||||
let type_tokens = field.type_tokens(true);
|
||||
|
@ -2072,7 +2088,7 @@ fn generate_funcptr(fnptr: &vkxml::FunctionPointer) -> TokenStream {
|
|||
quote! {
|
||||
#[allow(non_camel_case_types)]
|
||||
#[doc = #khronos_link]
|
||||
pub type #name = Option<unsafe extern "system" fn(#(#params),*) -> #ret_ty_tokens>;
|
||||
pub type #name = Option<unsafe extern "system" fn(#(#params),*) #ret_ty_tokens>;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue