Skip to content

Commit

Permalink
Option to represent all C++ operators.
Browse files Browse the repository at this point in the history
In its default behavior, bindgen does not emit information for any
C++ operatorXYZ function (unless operatorXYZ is a valid identifier,
which it isn't for C++ overloaded operators).

This PR introduces a new command line option to represent all operators.
This is not useful for those who directly consume the output of bindgen,
but is useful for post-processors. Specifically, consumers will need to
implement the callback to rename these items to something more useful.

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

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

9 changes: 9 additions & 0 deletions bindgen-tests/tests/headers/operator_equals.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// bindgen-flags: --represent-cxx-operators --generate-inline-functions -- -x c++
// bindgen-parse-callbacks: operator-rename

class SomeClass {
public:
bool operator=(const SomeClass& another) {
return false;
}
};
14 changes: 14 additions & 0 deletions bindgen-tests/tests/parse_callbacks/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,19 @@ impl ParseCallbacks for WrapAsVariadicFn {
}
}

#[derive(Debug)]
pub(super) struct OperatorRename;

impl ParseCallbacks for OperatorRename {
fn generated_name_override(&self, info: ItemInfo) -> Option<String> {
if info.name == "operator=" {
Some("operatorequals".to_string())
} else {
None
}
}
}

pub fn lookup(cb: &str) -> Box<dyn ParseCallbacks> {
match cb {
"enum-variant-rename" => Box::new(EnumVariantRename),
Expand All @@ -154,6 +167,7 @@ pub fn lookup(cb: &str) -> Box<dyn ParseCallbacks> {
}
"wrap-as-variadic-fn" => Box::new(WrapAsVariadicFn),
"type-visibility" => Box::new(TypeVisibility),
"operator-rename" => Box::new(OperatorRename),
call_back => {
if let Some(prefix) =
call_back.strip_prefix("remove-function-prefix-")
Expand Down
2 changes: 1 addition & 1 deletion bindgen/ir/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,7 @@ impl FunctionSig {
spelling.starts_with("operator") &&
!clang::is_valid_identifier(spelling)
};
if is_operator(&spelling) {
if is_operator(&spelling) && !ctx.options().represent_cxx_operators {
return Err(ParseError::Continue);
}

Expand Down
5 changes: 5 additions & 0 deletions bindgen/options/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,9 @@ struct BindgenCommand {
/// Use distinct char16_t
#[arg(long)]
use_distinct_char16_t: bool,
/// Output C++ overloaded operators
#[arg(long)]
represent_cxx_operators: bool,
/// Enables generation of vtable functions.
#[arg(long)]
vtable_generation: bool,
Expand Down Expand Up @@ -633,6 +636,7 @@ where
c_naming,
explicit_padding,
use_distinct_char16_t,
represent_cxx_operators,
vtable_generation,
sort_semantically,
merge_extern_blocks,
Expand Down Expand Up @@ -931,6 +935,7 @@ where
c_naming,
explicit_padding,
use_distinct_char16_t,
represent_cxx_operators,
vtable_generation,
sort_semantically,
merge_extern_blocks,
Expand Down
18 changes: 18 additions & 0 deletions bindgen/options/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,24 @@ options! {
},
as_args: "--use-distinct-char16-t",
},
/// Whether we should output C++ overloaded operators. By itself,
/// this option is not sufficient to produce valid output, because
/// such operators will have names that are not acceptable Rust
/// names (for example `operator=`). If you use this option, you'll also
/// have to rename the resulting functions - for example by using
/// [`ParseCallbacks::generated_name_override`].
represent_cxx_operators: bool {
methods: {
/// If this is true, output existence of C++ overloaded operators.
/// At present, only operator= is noted.
/// Disabled by default.
pub fn represent_cxx_operators(mut self, doit: bool) -> Builder {
self.options.represent_cxx_operators = doit;
self
}
},
as_args: "--represent-cxx-operators",
},

/// Types that have been blocklisted and should not appear anywhere in the generated code.
blocklisted_types: RegexSet {
Expand Down

0 comments on commit dbe5d3e

Please sign in to comment.