Skip to content

Commit

Permalink
add attributes to dynamic functions
Browse files Browse the repository at this point in the history
this includes comments and must_use annotations
  • Loading branch information
Emilgardis authored and emilio committed Mar 15, 2022
1 parent 310f7f8 commit 9689aec
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 10 deletions.
3 changes: 3 additions & 0 deletions src/codegen/dyngen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ impl DynamicItems {
}
}

#[allow(clippy::too_many_arguments)]
pub fn push(
&mut self,
ident: Ident,
Expand All @@ -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());
Expand Down Expand Up @@ -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
}
Expand Down
29 changes: 19 additions & 10 deletions src/codegen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand All @@ -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
Expand Down Expand Up @@ -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));
}
Expand Down Expand Up @@ -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));
}

Expand All @@ -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());
Expand All @@ -4040,6 +4048,7 @@ impl CodeGenerator for Function {
args_identifiers,
ret,
ret_ty,
attributes,
);
} else {
result.push(tokens);
Expand Down
56 changes: 56 additions & 0 deletions tests/expectations/tests/dynamic_loading_attributes.rs
Original file line number Diff line number Diff line change
@@ -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)()
}
}
11 changes: 11 additions & 0 deletions tests/headers/dynamic_loading_attributes.h
Original file line number Diff line number Diff line change
@@ -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() ;

0 comments on commit 9689aec

Please sign in to comment.