diff --git a/src/callbacks.rs b/src/callbacks.rs index 1b5445e642..0cdb01c8e1 100644 --- a/src/callbacks.rs +++ b/src/callbacks.rs @@ -21,6 +21,15 @@ impl Default for MacroParsingBehavior { } } +/// An enum specifying member type. +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub enum MemberType { + /// A member function. + Function, + /// A member variable. + Variable, +} + /// A trait to allow configuring different kinds of types in different /// situations. pub trait ParseCallbacks: fmt::Debug + UnwindSafe { @@ -65,6 +74,11 @@ pub trait ParseCallbacks: fmt::Debug + UnwindSafe { None } + /// Allows to rename a member name, replacing `_original_member_name`. + fn member_name(&self, _original_member_name: &str, _member_type: MemberType) -> Option { + None + } + /// This will be called on every file inclusion, with the full path of the included file. fn include_file(&self, _filename: &str) {} } diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index af1622daff..efcf455f19 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -15,6 +15,8 @@ use self::struct_layout::StructLayoutTracker; use super::BindgenOptions; +use crate::callbacks::MemberType; + use crate::ir::analysis::{HasVtable, Sizedness}; use crate::ir::annotations::FieldAccessorKind; use crate::ir::comment; @@ -1153,10 +1155,13 @@ impl<'a> FieldCodegen<'a> for FieldData { } } - let field_name = self - .name() - .map(|name| ctx.rust_mangle(name).into_owned()) - .expect("Each field should have a name in codegen!"); + let field_name = ctx.rust_mangle({ + let name = self.name().expect("Each field should have a name in codegen!").to_owned(); + ctx.parse_callbacks() + .and_then(|cb| cb.member_name(&name, MemberType::Variable)) + .unwrap_or(name) + .as_str() + }).into_owned(); let field_ident = ctx.rust_ident_raw(field_name.as_str()); if !parent.is_union() { @@ -1594,7 +1599,11 @@ impl CodeGenerator for CompInfo { let inner_item = ctx.resolve_item(base.ty); let mut inner = inner_item.to_rust_ty_or_opaque(ctx, &()); inner.append_implicit_template_params(ctx, &inner_item); - let field_name = ctx.rust_ident(&base.field_name); + let field_name = ctx.rust_ident( + ctx.parse_callbacks() + .and_then(|cb| cb.member_name(&base.field_name, MemberType::Variable)) + .unwrap_or(base.field_name.clone()) + ); struct_layout.saw_base(inner_item.expect_type()); @@ -1953,7 +1962,12 @@ impl CodeGenerator for CompInfo { let name = field.name().unwrap(); field.offset().and_then(|offset| { let field_offset = offset / 8; - let field_name = ctx.rust_ident(name); + let field_name = ctx.rust_ident( + ctx.parse_callbacks() + .and_then(|cb| cb.member_name(&name, MemberType::Variable)) + .unwrap_or(name.to_string()) + .as_str() + ); Some(quote! { assert_eq!( @@ -2157,7 +2171,12 @@ impl MethodCodegen for Method { let mut name = match self.kind() { MethodKind::Constructor => "new".into(), MethodKind::Destructor => "destruct".into(), - _ => function.name().to_owned(), + _ => { + let name = function.name().to_owned(); + ctx.parse_callbacks() + .and_then(|cb| cb.member_name(&name, MemberType::Function)) + .unwrap_or(name) + } }; let signature = match *signature_item.expect_type().kind() {