Skip to content

Commit

Permalink
Provide option to get real virtual fn receiver.
Browse files Browse the repository at this point in the history
For virtual functions, bindgen has traditionally emitted a void* pointer
because that's the least bad option for Rust code directly consuming the
bindings. For downstream postprocessors and code generators, this throws away
useful information about the actual type of the receiver. Provide a
command-line option to put that back.

Part of google/autocxx#124
  • Loading branch information
adetaylor committed Feb 20, 2025
1 parent 0df4256 commit 59c9507
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 1 deletion.
28 changes: 28 additions & 0 deletions bindgen-tests/tests/expectations/tests/specific_receiver.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions bindgen-tests/tests/headers/specific_receiver.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// bindgen-flags: --use-specific-virtual-function-receiver --generate-inline-functions -- -x c++ -std=c++14

class Fish {
public:
virtual void swim() {
}
};
5 changes: 4 additions & 1 deletion bindgen/ir/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -533,7 +533,10 @@ impl FunctionSig {
let is_const = is_method && cursor.method_is_const();
let is_virtual = is_method && cursor.method_is_virtual();
let is_static = is_method && cursor.method_is_static();
if !is_static && !is_virtual {
if !is_static &&
(!is_virtual ||
ctx.options().use_specific_virtual_function_receiver)
{
let parent = cursor.semantic_parent();
let class = Item::parse(parent, None, ctx)
.expect("Expected to parse the class");
Expand Down
5 changes: 5 additions & 0 deletions bindgen/options/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,9 @@ struct BindgenCommand {
/// Always output explicit padding fields.
#[arg(long)]
explicit_padding: bool,
/// Always be specific about the 'receiver' of a virtual function.
#[arg(long)]
use_specific_virtual_function_receiver: bool,
/// Use distinct char16_t
#[arg(long)]
use_distinct_char16_t: bool,
Expand Down Expand Up @@ -632,6 +635,7 @@ where
translate_enum_integer_types,
c_naming,
explicit_padding,
use_specific_virtual_function_receiver,
use_distinct_char16_t,
vtable_generation,
sort_semantically,
Expand Down Expand Up @@ -930,6 +934,7 @@ where
translate_enum_integer_types,
c_naming,
explicit_padding,
use_specific_virtual_function_receiver,
use_distinct_char16_t,
vtable_generation,
sort_semantically,
Expand Down
15 changes: 15 additions & 0 deletions bindgen/options/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,21 @@ macro_rules! options {
}

options! {
/// Whether to specify the type of a virtual function receiver
use_specific_virtual_function_receiver: bool {
methods: {
/// Normally, virtual functions have void* as their 'this' type.
/// If this flag is enabled, override that behavior to indicate a
/// pointer of the specific type.
/// Disabled by default.
pub fn use_specific_virtual_function_receiver(mut self, doit: bool) -> Builder {
self.options.use_specific_virtual_function_receiver = doit;
self
}
},
as_args: "--use-specific-virtual-function-receiver",
},

/// Whether we should distinguish between C++'s 'char16_t' and 'u16'.
/// The C++ type `char16_t` is its own special type; it's not a typedef
/// of some other integer (this differs from C).
Expand Down

0 comments on commit 59c9507

Please sign in to comment.