@@ -3,7 +3,7 @@ use std::ops::Deref;
33use syn:: punctuated:: Punctuated ;
44use syn:: visit:: Visit ;
55
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 } ;
77
88/// Represents a collected set of top-level Rust items relevant to FFI generation or analysis.
99///
@@ -94,6 +94,26 @@ fn collect_fields(fields: &Punctuated<syn::Field, syn::Token![,]>) -> Vec<Field>
9494 . collect ( )
9595}
9696
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+
97117fn visit_foreign_item_fn ( table : & mut FfiItems , i : & syn:: ForeignItemFn , abi : & Abi ) {
98118 let public = is_visible ( & i. vis ) ;
99119 let abi = abi. clone ( ) ;
@@ -121,11 +141,13 @@ fn visit_foreign_item_fn(table: &mut FfiItems, i: &syn::ForeignItemFn, abi: &Abi
121141 syn:: ReturnType :: Default => None ,
122142 syn:: ReturnType :: Type ( _, ty) => Some ( ty. deref ( ) . clone ( ) ) ,
123143 } ;
144+ let link_name = extract_single_link_name ( & i. attrs ) ;
124145
125146 table. foreign_functions . push ( Fn {
126147 public,
127148 abi,
128149 ident,
150+ link_name,
129151 parameters,
130152 return_type,
131153 } ) ;
@@ -136,11 +158,13 @@ fn visit_foreign_item_static(table: &mut FfiItems, i: &syn::ForeignItemStatic, a
136158 let abi = abi. clone ( ) ;
137159 let ident = i. ident . to_string ( ) . into_boxed_str ( ) ;
138160 let ty = i. ty . deref ( ) . clone ( ) ;
161+ let link_name = extract_single_link_name ( & i. attrs ) ;
139162
140163 table. foreign_statics . push ( Static {
141164 public,
142165 abi,
143166 ident,
167+ link_name,
144168 ty,
145169 } ) ;
146170}
0 commit comments