Skip to content

Commit 19c1f60

Browse files
adetayloremilio
authored andcommitted
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 fa2d8c3 commit 19c1f60

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
@@ -447,6 +447,9 @@ struct BindgenCommand {
447447
/// Use distinct char16_t
448448
#[arg(long)]
449449
use_distinct_char16_t: bool,
450+
/// Output C++ overloaded operators
451+
#[arg(long)]
452+
represent_cxx_operators: bool,
450453
/// Enables generation of vtable functions.
451454
#[arg(long)]
452455
vtable_generation: bool,
@@ -649,6 +652,7 @@ where
649652
explicit_padding,
650653
use_specific_virtual_function_receiver,
651654
use_distinct_char16_t,
655+
represent_cxx_operators,
652656
vtable_generation,
653657
sort_semantically,
654658
merge_extern_blocks,
@@ -951,6 +955,7 @@ where
951955
explicit_padding,
952956
use_specific_virtual_function_receiver,
953957
use_distinct_char16_t,
958+
represent_cxx_operators,
954959
vtable_generation,
955960
sort_semantically,
956961
merge_extern_blocks,

bindgen/options/mod.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,24 @@ options! {
192192
},
193193
as_args: "--use-distinct-char16-t",
194194
},
195+
/// Whether we should output C++ overloaded operators. By itself,
196+
/// this option is not sufficient to produce valid output, because
197+
/// such operators will have names that are not acceptable Rust
198+
/// names (for example `operator=`). If you use this option, you'll also
199+
/// have to rename the resulting functions - for example by using
200+
/// [`ParseCallbacks::generated_name_override`].
201+
represent_cxx_operators: bool {
202+
methods: {
203+
/// If this is true, output existence of C++ overloaded operators.
204+
/// At present, only operator= is noted.
205+
/// Disabled by default.
206+
pub fn represent_cxx_operators(mut self, doit: bool) -> Builder {
207+
self.options.represent_cxx_operators = doit;
208+
self
209+
}
210+
},
211+
as_args: "--represent-cxx-operators",
212+
},
195213

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

0 commit comments

Comments
 (0)