Skip to content

Commit dbe5d3e

Browse files
committed
Option to represent all C++ operators.
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
1 parent 0df4256 commit dbe5d3e

File tree

6 files changed

+71
-1
lines changed

6 files changed

+71
-1
lines changed

bindgen-tests/tests/expectations/tests/operator_equals.rs

Lines changed: 24 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// bindgen-flags: --represent-cxx-operators --generate-inline-functions -- -x c++
2+
// bindgen-parse-callbacks: operator-rename
3+
4+
class SomeClass {
5+
public:
6+
bool operator=(const SomeClass& another) {
7+
return false;
8+
}
9+
};

bindgen-tests/tests/parse_callbacks/mod.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,19 @@ impl ParseCallbacks for WrapAsVariadicFn {
146146
}
147147
}
148148

149+
#[derive(Debug)]
150+
pub(super) struct OperatorRename;
151+
152+
impl ParseCallbacks for OperatorRename {
153+
fn generated_name_override(&self, info: ItemInfo) -> Option<String> {
154+
if info.name == "operator=" {
155+
Some("operatorequals".to_string())
156+
} else {
157+
None
158+
}
159+
}
160+
}
161+
149162
pub fn lookup(cb: &str) -> Box<dyn ParseCallbacks> {
150163
match cb {
151164
"enum-variant-rename" => Box::new(EnumVariantRename),
@@ -154,6 +167,7 @@ pub fn lookup(cb: &str) -> Box<dyn ParseCallbacks> {
154167
}
155168
"wrap-as-variadic-fn" => Box::new(WrapAsVariadicFn),
156169
"type-visibility" => Box::new(TypeVisibility),
170+
"operator-rename" => Box::new(OperatorRename),
157171
call_back => {
158172
if let Some(prefix) =
159173
call_back.strip_prefix("remove-function-prefix-")

bindgen/ir/function.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,7 @@ impl FunctionSig {
433433
spelling.starts_with("operator") &&
434434
!clang::is_valid_identifier(spelling)
435435
};
436-
if is_operator(&spelling) {
436+
if is_operator(&spelling) && !ctx.options().represent_cxx_operators {
437437
return Err(ParseError::Continue);
438438
}
439439

bindgen/options/cli.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,9 @@ struct BindgenCommand {
444444
/// Use distinct char16_t
445445
#[arg(long)]
446446
use_distinct_char16_t: bool,
447+
/// Output C++ overloaded operators
448+
#[arg(long)]
449+
represent_cxx_operators: bool,
447450
/// Enables generation of vtable functions.
448451
#[arg(long)]
449452
vtable_generation: bool,
@@ -633,6 +636,7 @@ where
633636
c_naming,
634637
explicit_padding,
635638
use_distinct_char16_t,
639+
represent_cxx_operators,
636640
vtable_generation,
637641
sort_semantically,
638642
merge_extern_blocks,
@@ -931,6 +935,7 @@ where
931935
c_naming,
932936
explicit_padding,
933937
use_distinct_char16_t,
938+
represent_cxx_operators,
934939
vtable_generation,
935940
sort_semantically,
936941
merge_extern_blocks,

bindgen/options/mod.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,24 @@ options! {
177177
},
178178
as_args: "--use-distinct-char16-t",
179179
},
180+
/// Whether we should output C++ overloaded operators. By itself,
181+
/// this option is not sufficient to produce valid output, because
182+
/// such operators will have names that are not acceptable Rust
183+
/// names (for example `operator=`). If you use this option, you'll also
184+
/// have to rename the resulting functions - for example by using
185+
/// [`ParseCallbacks::generated_name_override`].
186+
represent_cxx_operators: bool {
187+
methods: {
188+
/// If this is true, output existence of C++ overloaded operators.
189+
/// At present, only operator= is noted.
190+
/// Disabled by default.
191+
pub fn represent_cxx_operators(mut self, doit: bool) -> Builder {
192+
self.options.represent_cxx_operators = doit;
193+
self
194+
}
195+
},
196+
as_args: "--represent-cxx-operators",
197+
},
180198

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

0 commit comments

Comments
 (0)