diff options
author | Emil Gardström <emil.gardstrom@gmail.com> | 2022-02-25 20:13:47 +0100 |
---|---|---|
committer | Emilio Cobos Álvarez <emilio@crisal.io> | 2022-03-15 04:00:08 +0100 |
commit | 9689aecbfe45c9ba18d6d95de3cb903b1740b8cf (patch) | |
tree | 7f30874b311f9c48954b5be631c9748e49beac6b | |
parent | 310f7f877042f0858cd01fb1c326a41d23bd821c (diff) |
add attributes to dynamic functions
this includes comments and must_use annotations
-rw-r--r-- | src/codegen/dyngen.rs | 3 | ||||
-rw-r--r-- | src/codegen/mod.rs | 29 | ||||
-rw-r--r-- | tests/expectations/tests/dynamic_loading_attributes.rs | 56 | ||||
-rw-r--r-- | tests/headers/dynamic_loading_attributes.h | 11 |
4 files changed, 89 insertions, 10 deletions
diff --git a/src/codegen/dyngen.rs b/src/codegen/dyngen.rs index 71c4dab1..26cfe5cc 100644 --- a/src/codegen/dyngen.rs +++ b/src/codegen/dyngen.rs @@ -112,6 +112,7 @@ impl DynamicItems { } } + #[allow(clippy::too_many_arguments)] pub fn push( &mut self, ident: Ident, @@ -122,6 +123,7 @@ impl DynamicItems { args_identifiers: Vec<proc_macro2::TokenStream>, ret: proc_macro2::TokenStream, ret_ty: proc_macro2::TokenStream, + attributes: Vec<proc_macro2::TokenStream>, ) { if !is_variadic { assert_eq!(args.len(), args_identifiers.len()); @@ -153,6 +155,7 @@ impl DynamicItems { // access the function pointer so that the user can call it just fine. if !is_variadic { self.struct_implementation.push(quote! { + #(#attributes)* pub unsafe fn #ident ( &self, #( #args ),* ) -> #ret_ty { #call_body } diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index b988a516..7c8e2646 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -3907,6 +3907,8 @@ impl CodeGenerator for Function { Linkage::External => {} } + #[allow(clippy::needless_late_init)] + let is_dynamic_function; // Pure virtual methods have no actual symbol, so we can't generate // something meaningful for them. match self.kind() { @@ -3915,7 +3917,14 @@ impl CodeGenerator for Function { { return None; } - _ => {} + FunctionKind::Function => { + // If we're generating for dynamic loading, some attributes can not be emitted. + is_dynamic_function = + ctx.options().dynamic_library_name.is_some() + } + _ => { + is_dynamic_function = false; + } } // Similar to static member variables in a class template, we can't @@ -3958,7 +3967,6 @@ impl CodeGenerator for Function { { attributes.push(attributes::must_use()); } - if let Some(comment) = item.comment(ctx) { attributes.push(attributes::doc(comment)); } @@ -3995,11 +4003,13 @@ impl CodeGenerator for Function { } let link_name = mangled_name.unwrap_or(name); - if !utils::names_will_be_identical_after_mangling( - &canonical_name, - link_name, - Some(abi), - ) { + if !is_dynamic_function && + !utils::names_will_be_identical_after_mangling( + &canonical_name, + link_name, + Some(abi), + ) + { attributes.push(attributes::link_name(link_name)); } @@ -4021,9 +4031,7 @@ impl CodeGenerator for Function { }; // If we're doing dynamic binding generation, add to the dynamic items. - if ctx.options().dynamic_library_name.is_some() && - self.kind() == FunctionKind::Function - { + if is_dynamic_function { let args_identifiers = utils::fnsig_argument_identifiers(ctx, signature); let return_item = ctx.resolve_item(signature.return_type()); @@ -4040,6 +4048,7 @@ impl CodeGenerator for Function { args_identifiers, ret, ret_ty, + attributes, ); } else { result.push(tokens); diff --git a/tests/expectations/tests/dynamic_loading_attributes.rs b/tests/expectations/tests/dynamic_loading_attributes.rs new file mode 100644 index 00000000..b50fbd08 --- /dev/null +++ b/tests/expectations/tests/dynamic_loading_attributes.rs @@ -0,0 +1,56 @@ +#![allow( + dead_code, + non_snake_case, + non_camel_case_types, + non_upper_case_globals +)] + +extern crate libloading; +pub struct TestLib { + __library: ::libloading::Library, + pub foo: unsafe extern "C" fn( + x: ::std::os::raw::c_int, + y: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int, + pub baz: unsafe extern "C" fn() -> ::std::os::raw::c_int, +} +impl TestLib { + pub unsafe fn new<P>(path: P) -> Result<Self, ::libloading::Error> + where + P: AsRef<::std::ffi::OsStr>, + { + let library = ::libloading::Library::new(path)?; + Self::from_library(library) + } + pub unsafe fn from_library<L>( + library: L, + ) -> Result<Self, ::libloading::Error> + where + L: Into<::libloading::Library>, + { + let __library = library.into(); + let foo = __library.get(b"foo\0").map(|sym| *sym)?; + let baz = __library.get(b"baz\0").map(|sym| *sym)?; + Ok(TestLib { + __library, + foo, + baz, + }) + } + #[must_use] + #[doc = " @brief A function"] + #[doc = ""] + #[doc = " @param x"] + #[doc = " @param y"] + #[doc = " @return int"] + pub unsafe fn foo( + &self, + x: ::std::os::raw::c_int, + y: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int { + (self.foo)(x, y) + } + pub unsafe fn baz(&self) -> ::std::os::raw::c_int { + (self.baz)() + } +} diff --git a/tests/headers/dynamic_loading_attributes.h b/tests/headers/dynamic_loading_attributes.h new file mode 100644 index 00000000..e2ca62b1 --- /dev/null +++ b/tests/headers/dynamic_loading_attributes.h @@ -0,0 +1,11 @@ +// bindgen-flags: --dynamic-loading TestLib --dynamic-link-require-all --enable-function-attribute-detection +/** + * @brief A function + * + * @param x + * @param y + * @return int + */ +__attribute__((warn_unused_result)) +int foo(int x, int y); +int baz() ; |