Skip to content

Commit 9689aec

Browse files
Emilgardisemilio
authored andcommitted
add attributes to dynamic functions
this includes comments and must_use annotations
1 parent 310f7f8 commit 9689aec

File tree

4 files changed

+89
-10
lines changed

4 files changed

+89
-10
lines changed

src/codegen/dyngen.rs

+3
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ impl DynamicItems {
112112
}
113113
}
114114

115+
#[allow(clippy::too_many_arguments)]
115116
pub fn push(
116117
&mut self,
117118
ident: Ident,
@@ -122,6 +123,7 @@ impl DynamicItems {
122123
args_identifiers: Vec<proc_macro2::TokenStream>,
123124
ret: proc_macro2::TokenStream,
124125
ret_ty: proc_macro2::TokenStream,
126+
attributes: Vec<proc_macro2::TokenStream>,
125127
) {
126128
if !is_variadic {
127129
assert_eq!(args.len(), args_identifiers.len());
@@ -153,6 +155,7 @@ impl DynamicItems {
153155
// access the function pointer so that the user can call it just fine.
154156
if !is_variadic {
155157
self.struct_implementation.push(quote! {
158+
#(#attributes)*
156159
pub unsafe fn #ident ( &self, #( #args ),* ) -> #ret_ty {
157160
#call_body
158161
}

src/codegen/mod.rs

+19-10
Original file line numberDiff line numberDiff line change
@@ -3907,6 +3907,8 @@ impl CodeGenerator for Function {
39073907
Linkage::External => {}
39083908
}
39093909

3910+
#[allow(clippy::needless_late_init)]
3911+
let is_dynamic_function;
39103912
// Pure virtual methods have no actual symbol, so we can't generate
39113913
// something meaningful for them.
39123914
match self.kind() {
@@ -3915,7 +3917,14 @@ impl CodeGenerator for Function {
39153917
{
39163918
return None;
39173919
}
3918-
_ => {}
3920+
FunctionKind::Function => {
3921+
// If we're generating for dynamic loading, some attributes can not be emitted.
3922+
is_dynamic_function =
3923+
ctx.options().dynamic_library_name.is_some()
3924+
}
3925+
_ => {
3926+
is_dynamic_function = false;
3927+
}
39193928
}
39203929

39213930
// Similar to static member variables in a class template, we can't
@@ -3958,7 +3967,6 @@ impl CodeGenerator for Function {
39583967
{
39593968
attributes.push(attributes::must_use());
39603969
}
3961-
39623970
if let Some(comment) = item.comment(ctx) {
39633971
attributes.push(attributes::doc(comment));
39643972
}
@@ -3995,11 +4003,13 @@ impl CodeGenerator for Function {
39954003
}
39964004

39974005
let link_name = mangled_name.unwrap_or(name);
3998-
if !utils::names_will_be_identical_after_mangling(
3999-
&canonical_name,
4000-
link_name,
4001-
Some(abi),
4002-
) {
4006+
if !is_dynamic_function &&
4007+
!utils::names_will_be_identical_after_mangling(
4008+
&canonical_name,
4009+
link_name,
4010+
Some(abi),
4011+
)
4012+
{
40034013
attributes.push(attributes::link_name(link_name));
40044014
}
40054015

@@ -4021,9 +4031,7 @@ impl CodeGenerator for Function {
40214031
};
40224032

40234033
// If we're doing dynamic binding generation, add to the dynamic items.
4024-
if ctx.options().dynamic_library_name.is_some() &&
4025-
self.kind() == FunctionKind::Function
4026-
{
4034+
if is_dynamic_function {
40274035
let args_identifiers =
40284036
utils::fnsig_argument_identifiers(ctx, signature);
40294037
let return_item = ctx.resolve_item(signature.return_type());
@@ -4040,6 +4048,7 @@ impl CodeGenerator for Function {
40404048
args_identifiers,
40414049
ret,
40424050
ret_ty,
4051+
attributes,
40434052
);
40444053
} else {
40454054
result.push(tokens);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#![allow(
2+
dead_code,
3+
non_snake_case,
4+
non_camel_case_types,
5+
non_upper_case_globals
6+
)]
7+
8+
extern crate libloading;
9+
pub struct TestLib {
10+
__library: ::libloading::Library,
11+
pub foo: unsafe extern "C" fn(
12+
x: ::std::os::raw::c_int,
13+
y: ::std::os::raw::c_int,
14+
) -> ::std::os::raw::c_int,
15+
pub baz: unsafe extern "C" fn() -> ::std::os::raw::c_int,
16+
}
17+
impl TestLib {
18+
pub unsafe fn new<P>(path: P) -> Result<Self, ::libloading::Error>
19+
where
20+
P: AsRef<::std::ffi::OsStr>,
21+
{
22+
let library = ::libloading::Library::new(path)?;
23+
Self::from_library(library)
24+
}
25+
pub unsafe fn from_library<L>(
26+
library: L,
27+
) -> Result<Self, ::libloading::Error>
28+
where
29+
L: Into<::libloading::Library>,
30+
{
31+
let __library = library.into();
32+
let foo = __library.get(b"foo\0").map(|sym| *sym)?;
33+
let baz = __library.get(b"baz\0").map(|sym| *sym)?;
34+
Ok(TestLib {
35+
__library,
36+
foo,
37+
baz,
38+
})
39+
}
40+
#[must_use]
41+
#[doc = " @brief A function"]
42+
#[doc = ""]
43+
#[doc = " @param x"]
44+
#[doc = " @param y"]
45+
#[doc = " @return int"]
46+
pub unsafe fn foo(
47+
&self,
48+
x: ::std::os::raw::c_int,
49+
y: ::std::os::raw::c_int,
50+
) -> ::std::os::raw::c_int {
51+
(self.foo)(x, y)
52+
}
53+
pub unsafe fn baz(&self) -> ::std::os::raw::c_int {
54+
(self.baz)()
55+
}
56+
}
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// bindgen-flags: --dynamic-loading TestLib --dynamic-link-require-all --enable-function-attribute-detection
2+
/**
3+
* @brief A function
4+
*
5+
* @param x
6+
* @param y
7+
* @return int
8+
*/
9+
__attribute__((warn_unused_result))
10+
int foo(int x, int y);
11+
int baz() ;

0 commit comments

Comments
 (0)