From f1860bde5e62604864a19250c0e1e6caebd6c3fd Mon Sep 17 00:00:00 2001 From: Leonardo Di Giovanna Date: Sat, 26 Apr 2025 17:51:30 +0200 Subject: [PATCH] feat: add field attributes support Signed-off-by: Leonardo Di Giovanna --- .../expectations/tests/field_attributes.rs | 19 +++++++++++++++++++ .../tests/headers/field_attributes.h | 6 ++++++ bindgen/codegen/mod.rs | 10 ++++++++++ bindgen/ir/annotations.rs | 2 +- 4 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 bindgen-tests/tests/expectations/tests/field_attributes.rs create mode 100644 bindgen-tests/tests/headers/field_attributes.h diff --git a/bindgen-tests/tests/expectations/tests/field_attributes.rs b/bindgen-tests/tests/expectations/tests/field_attributes.rs new file mode 100644 index 0000000000..7fd8277e09 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/field_attributes.rs @@ -0,0 +1,19 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct S { + ///
+ #[deprecated] + #[cfg(not(any(foo, bar)))] + pub field_1: ::std::os::raw::c_int, + ///
+ #[cfg(not(baz))] + pub field_2: ::std::os::raw::c_char, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of S"][::std::mem::size_of::() - 8usize]; + ["Alignment of S"][::std::mem::align_of::() - 4usize]; + ["Offset of field: S::field_1"][::std::mem::offset_of!(S, field_1) - 0usize]; + ["Offset of field: S::field_2"][::std::mem::offset_of!(S, field_2) - 4usize]; +}; diff --git a/bindgen-tests/tests/headers/field_attributes.h b/bindgen-tests/tests/headers/field_attributes.h new file mode 100644 index 0000000000..ca6ae4f8a4 --- /dev/null +++ b/bindgen-tests/tests/headers/field_attributes.h @@ -0,0 +1,6 @@ +struct S { + ///
+ int field_1; + ///
+ char field_2; +}; diff --git a/bindgen/codegen/mod.rs b/bindgen/codegen/mod.rs index 8da10ff051..4bbcec6f1f 100644 --- a/bindgen/codegen/mod.rs +++ b/bindgen/codegen/mod.rs @@ -1567,19 +1567,29 @@ impl FieldCodegen<'_> for FieldData { let accessor_kind = self.annotations().accessor_kind().unwrap_or(accessor_kind); + let attributes: Vec = self + .annotations() + .attributes() + .iter() + .map(|s| s.parse().unwrap()) + .collect::>(); + match visibility { FieldVisibilityKind::Private => { field.append_all(quote! { + #( #attributes )* #field_ident : #ty , }); } FieldVisibilityKind::PublicCrate => { field.append_all(quote! { + #( #attributes )* pub(crate) #field_ident : #ty , }); } FieldVisibilityKind::Public => { field.append_all(quote! { + #( #attributes )* pub #field_ident : #ty , }); } diff --git a/bindgen/ir/annotations.rs b/bindgen/ir/annotations.rs index 7f5d74b3ee..a0b6e5c907 100644 --- a/bindgen/ir/annotations.rs +++ b/bindgen/ir/annotations.rs @@ -102,7 +102,7 @@ pub(crate) struct Annotations { constify_enum_variant: bool, /// List of explicit derives for this type. derives: Vec, - /// List of explicit attributes for this type. + /// List of explicit attributes for this type/field. attributes: Vec, }