@@ -3,7 +3,7 @@ use std::ops::Deref;
3
3
use syn:: punctuated:: Punctuated ;
4
4
use syn:: visit:: Visit ;
5
5
6
- use crate :: { Abi , Const , Field , Fn , Parameter , Static , Struct , Type , Union } ;
6
+ use crate :: { Abi , BoxStr , Const , Field , Fn , Parameter , Static , Struct , Type , Union } ;
7
7
8
8
/// Represents a collected set of top-level Rust items relevant to FFI generation or analysis.
9
9
///
@@ -94,6 +94,26 @@ fn collect_fields(fields: &Punctuated<syn::Field, syn::Token![,]>) -> Vec<Field>
94
94
. collect ( )
95
95
}
96
96
97
+ fn extract_single_link_name ( attrs : & [ syn:: Attribute ] ) -> Option < BoxStr > {
98
+ let mut link_name_iter = attrs
99
+ . iter ( )
100
+ . filter ( |attr| attr. path ( ) . is_ident ( "link_name" ) ) ;
101
+
102
+ let link_name = link_name_iter. next ( ) ?;
103
+ if let Some ( attr) = link_name_iter. next ( ) {
104
+ panic ! ( "multiple `#[link_name = ...]` attributes found: {attr:?}" ) ;
105
+ }
106
+
107
+ if let syn:: Meta :: NameValue ( nv) = & link_name. meta
108
+ && let syn:: Expr :: Lit ( expr_lit) = & nv. value
109
+ && let syn:: Lit :: Str ( lit_str) = & expr_lit. lit
110
+ {
111
+ return Some ( lit_str. value ( ) . into_boxed_str ( ) ) ;
112
+ }
113
+
114
+ panic ! ( "unrecognized `link_name` syntax: {link_name:?}" ) ;
115
+ }
116
+
97
117
fn visit_foreign_item_fn ( table : & mut FfiItems , i : & syn:: ForeignItemFn , abi : & Abi ) {
98
118
let public = is_visible ( & i. vis ) ;
99
119
let abi = abi. clone ( ) ;
@@ -121,11 +141,13 @@ fn visit_foreign_item_fn(table: &mut FfiItems, i: &syn::ForeignItemFn, abi: &Abi
121
141
syn:: ReturnType :: Default => None ,
122
142
syn:: ReturnType :: Type ( _, ty) => Some ( ty. deref ( ) . clone ( ) ) ,
123
143
} ;
144
+ let link_name = extract_single_link_name ( & i. attrs ) ;
124
145
125
146
table. foreign_functions . push ( Fn {
126
147
public,
127
148
abi,
128
149
ident,
150
+ link_name,
129
151
parameters,
130
152
return_type,
131
153
} ) ;
@@ -136,11 +158,13 @@ fn visit_foreign_item_static(table: &mut FfiItems, i: &syn::ForeignItemStatic, a
136
158
let abi = abi. clone ( ) ;
137
159
let ident = i. ident . to_string ( ) . into_boxed_str ( ) ;
138
160
let ty = i. ty . deref ( ) . clone ( ) ;
161
+ let link_name = extract_single_link_name ( & i. attrs ) ;
139
162
140
163
table. foreign_statics . push ( Static {
141
164
public,
142
165
abi,
143
166
ident,
167
+ link_name,
144
168
ty,
145
169
} ) ;
146
170
}
0 commit comments