Handle C++23 explicit object member functions - #3457
Conversation
|
r? @emilio |
| let actual = builder() | ||
| .disable_header_comment() | ||
| .header_contents( | ||
| "test.hpp", |
There was a problem hiding this comment.
Why can't it use our regular tests infra? We could skip that test in older clang versions if needed.
There was a problem hiding this comment.
The regression now uses the regular header/expectation infrastructure. The bindgen-min-clang-version: 18 marker skips it on older libclang versions, while libclang 18 and newer follow the normal generation and comparison path.
| let is_static = cur.method_is_static(); | ||
| let is_static = cur.kind() == CXCursor_CXXMethod && | ||
| (cur.method_is_static() || | ||
| cur.method_is_explicit_object()); |
There was a problem hiding this comment.
Doesn't look like a static method to me.
There was a problem hiding this comment.
Explicit-object members now use MethodKind::ExplicitObject rather than Static. This preserves the declared object parameter without injecting an implicit receiver while keeping the method classified as non-static.
| let is_static = cur.kind() == CXCursor_CXXMethod && | ||
| (cur.method_is_static() || | ||
| cur.method_is_explicit_object()); | ||
| debug_assert!(!(is_static && is_virtual), "How?"); |
There was a problem hiding this comment.
Can't you use virtual with explicit this? If so this assert would break?
There was a problem hiding this comment.
C++23 dcl.fct prohibits a member function with an explicit object parameter from being declared virtual. Clang confirms this rule, so well-formed input cannot violate the assertion. Explicit-object members remain separate from both static and virtual methods.
Detect explicit object parameters from the first parameter token because libclang does not expose this distinction directly. Represent those members separately from static methods so their declared object parameter is preserved without injecting an implicit receiver. Move the regression into the standard header expectation infrastructure with a minimum libclang version marker, covering value and reference receivers while leaving ordinary member functions unchanged. Fixes rust-lang#3441 Developed with assistance from OpenAI Codex.
a9cc3c2 to
3b8da28
Compare
|
Thanks for the review. I initially classified explicit-object members as static because neither form has an implicit In The generated bindings now retain |
|
Requested reviewer is already assigned to this pull request. Please choose another assignee. |
Fixes #3441.
What changed
libclang represents a C++23 explicit object parameter as the first ParmDecl, but exposes no dedicated C API for identifying it. Bindgen previously treated the enclosing CXXMethod as an ordinary member and inserted an additional implicit this pointer.
This change detects the leading this keyword on the first parameter and treats the method as receiver-free during IR construction. The declared object parameter remains in the generated FFI signature, and the Rust convenience wrapper becomes an associated function instead of replacing that parameter with &self.
The regression test covers a by-value explicit object parameter, an attributed lvalue-reference parameter, and an ordinary member method to ensure existing receiver generation is unchanged.
Verification
Implementation and tests were developed with assistance from OpenAI Codex.