-
Notifications
You must be signed in to change notification settings - Fork 748
Bindgen doesn't generate "stdcall" calling convention on x86_64-pc-windows-msvc #1433
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
Comments
On further thought, I don't like that bindgen produces e.g. if I run bindgen using /* automatically generated by rust-bindgen */
pub type MPI_Datatype = ::std::os::raw::c_int;
pub type MPI_Op = ::std::os::raw::c_int;
extern "stdcall" {
#[link_name = "\u{1}_MPI_Op_create@12"]
pub fn MPI_Op_create(
user_fn: ::std::option::Option<unsafe extern "stdcall" fn()>,
commute: ::std::os::raw::c_int,
op: *mut MPI_Op,
) -> ::std::os::raw::c_int;
} Even once the function signature issue is fixed, this would then result in the user having to do Of course, I don't know if there's anything bindgen can do if Clang is reporting that the calling convention is cdecl on 64-bit Windows, even when __stdcall was used. |
Yeah, I agree it'd be nice to use For reference this is the diff between diff --git a/emit.txt b/emit2.txt
index 5f0a8f22..8c42dd99 100644
--- a/emit.txt
+++ b/emit2.txt
@@ -333,23 +333,23 @@
semantic-parent.kind = TranslationUnit
semantic-parent.spelling = "t.h"
semantic-parent.location = builtin definitions
semantic-parent.is-definition? false
semantic-parent.is-declaration? false
semantic-parent.is-inlined-function? false
type.kind = FunctionProto
- type.cconv = 2
- type.spelling = "int (MPI_User_function *, int, MPI_Op *) __attribute__((stdcall))"
+ type.cconv = 1
+ type.spelling = "int (MPI_User_function *, int, MPI_Op *)"
type.is-variadic? false
type.canonical.kind = FunctionProto
- type.canonical.cconv = 2
- type.canonical.spelling = "int (void (*)(void *, void *, int *, int *) __attribute__((stdcall)), int, int *) __attribute__((stdcall))"
+ type.canonical.cconv = 1
+ type.canonical.spelling = "int (void (*)(void *, void *, int *, int *), int, int *)"
type.canonical.is-variadic? false
type.canonical.return.kind = Int
type.canonical.return.cconv = 100
type.canonical.return.spelling = "int"
type.canonical.return.is-variadic? false
type.return.kind = Int
@@ -385,22 +385,22 @@
type.kind = Pointer
type.cconv = 100
type.spelling = "MPI_User_function *"
type.is-variadic? false
type.canonical.kind = Pointer
type.canonical.cconv = 100
- type.canonical.spelling = "void (*)(void *, void *, int *, int *) __attribute__((stdcall))"
+ type.canonical.spelling = "void (*)(void *, void *, int *, int *)"
type.canonical.is-variadic? false
type.canonical.pointee.kind = FunctionProto
- type.canonical.pointee.cconv = 2
- type.canonical.pointee.spelling = "void (void *, void *, int *, int *) __attribute__((stdcall))"
+ type.canonical.pointee.cconv = 1
+ type.canonical.pointee.spelling = "void (void *, void *, int *, int *)"
type.canonical.pointee.is-variadic? false
type.canonical.pointee.return.kind = Void
type.canonical.pointee.return.cconv = 100
type.canonical.pointee.return.spelling = "void"
type.canonical.pointee.return.is-variadic? false
type.pointee.kind = FunctionProto
@@ -602,16 +602,15 @@
type.declaration.semantic-parent.is-inlined-function? false
)
)
)
/* automatically generated by rust-bindgen */
pub type MPI_Datatype = ::std::os::raw::c_int;
pub type MPI_Op = ::std::os::raw::c_int;
-extern "stdcall" {
- #[link_name = "\u{1}_MPI_Op_create@12"]
+extern "C" {
pub fn MPI_Op_create(
- user_fn: ::std::option::Option<unsafe extern "stdcall" fn()>,
+ user_fn: ::std::option::Option<unsafe extern "C" fn()>,
commute: ::std::os::raw::c_int,
op: *mut MPI_Op,
) -> ::std::os::raw::c_int;
} So we cannot even try to detect it hackily via checking |
Closing as it's an upstream libclang issue and I don't think we can work around it easily. Thanks for reporting it though! :) |
Thanks for looking at this emilio. However, there's a second issue here I think you missed: The function signature for any "stdcall" function pointer type is decaying to just pub type MPI_User_function = ::std::option::Option<
unsafe extern "C" fn(
invec: *mut ::std::os::raw::c_void,
inoutvec: *mut ::std::os::raw::c_void,
len: *mut ::std::os::raw::c_int,
datatype: *mut MPI_Datatype,
),
>;
extern "C" {
pub fn MPI_Op_create(
user_fn: MPI_User_function,
commute: ::std::os::raw::c_int,
op: *mut MPI_Op,
) -> ::std::os::raw::c_int;
} but instead it's just: extern "C" {
pub fn MPI_Op_create(
user_fn: ::std::option::Option<unsafe extern "C" fn()>,
commute: ::std::os::raw::c_int,
op: *mut MPI_Op,
) -> ::std::os::raw::c_int;
} |
Hmm, sorry, yeah, I had missed that. It preserves the calling convention right, but you're right that the alias is not properly generated, that deserves a bit more investigation. FWIW the stdcall stuff is a bit messy, see #1403 and previous bits. The issue is that clang only puts the real calling convention at some places, so maybe we're just confused, or maybe it's the clang ast messing with us. |
did anything change with clang? |
It seems that stdcall is now included in the AST as of clang 10:
|
Additionally, the correct function pointer signature is emitted in the AST, but bindgen still has the undesirable behavior, so it's getting lost somewhere in translation. |
We're using clang_getFunctionTypeCallingConv to get the right calling convention, the relevant functions return the It does the right thing if you specify |
I ran bindgen with this input
using both /* automatically generated by rust-bindgen 0.63.0 */
pub type MPI_Datatype = ::std::os::raw::c_int;
pub type MPI_Op = ::std::os::raw::c_int;
extern "stdcall" {
pub fn MPI_Op_create(
user_fn: ::std::option::Option<
unsafe extern "stdcall" fn(
arg1: *mut ::std::os::raw::c_void,
arg2: *mut ::std::os::raw::c_void,
arg3: *mut ::std::os::raw::c_int,
arg4: *mut MPI_Datatype,
),
>,
commute: ::std::os::raw::c_int,
op: *mut MPI_Op,
) -> ::std::os::raw::c_int;
} I have clang 14 on my system just in case. |
Versions
Windows 10, 64-bit
clang
bindgen
Input C/C++ Header
(snipped from MS-MPI's mpi.h header)
Bindgen Invocation
Actual Results
Expected Results
Comments
emit-clang-ast.txt
I've attached the results of
--emit-clang-ast
. I haven't looked at this output before, so apologies if I'm misinterpreting. It does appear that both the functionMPI_Op_create
and the function prototypeMPI_User_function
are receivingcconv = 1
, which looks like it's the C calling convention. I think this is actually correct for 64-bit Windows - stdcall and C are now the same.Even if it's correct to mark them as
extern "C"
, which I'm fine with, it's still a bug thatMPI_User_function
isn't being defined, and the type signature ofMPI_Op_create
is incorrect.Thank you!
The text was updated successfully, but these errors were encountered: