@@ -32,7 +32,7 @@ use driver::config::{NoDebugInfo, FullDebugInfo};
32
32
use driver:: driver:: { CrateAnalysis , CrateTranslation , ModuleTranslation } ;
33
33
use driver:: session:: Session ;
34
34
use lint;
35
- use llvm:: { BasicBlockRef , ValueRef , Vector , get_param} ;
35
+ use llvm:: { BasicBlockRef , Linkage , ValueRef , Vector , get_param} ;
36
36
use llvm;
37
37
use metadata:: { csearch, encoder, loader} ;
38
38
use middle:: astencode;
@@ -2153,6 +2153,32 @@ impl<'a, 'tcx, 'v> Visitor<'v> for TransItemVisitor<'a, 'tcx> {
2153
2153
}
2154
2154
}
2155
2155
2156
+ pub fn llvm_linkage_by_name ( name : & str ) -> Option < Linkage > {
2157
+ // Use the names from src/llvm/docs/LangRef.rst here. Most types are only
2158
+ // applicable to variable declarations and may not really make sense for
2159
+ // Rust code in the first place but whitelist them anyway and trust that
2160
+ // the user knows what s/he's doing. Who knows, unanticipated use cases
2161
+ // may pop up in the future.
2162
+ //
2163
+ // ghost, dllimport, dllexport and linkonce_odr_autohide are not supported
2164
+ // and don't have to be, LLVM treats them as no-ops.
2165
+ match name {
2166
+ "appending" => Some ( llvm:: AppendingLinkage ) ,
2167
+ "available_externally" => Some ( llvm:: AvailableExternallyLinkage ) ,
2168
+ "common" => Some ( llvm:: CommonLinkage ) ,
2169
+ "extern_weak" => Some ( llvm:: ExternalWeakLinkage ) ,
2170
+ "external" => Some ( llvm:: ExternalLinkage ) ,
2171
+ "internal" => Some ( llvm:: InternalLinkage ) ,
2172
+ "linkonce" => Some ( llvm:: LinkOnceAnyLinkage ) ,
2173
+ "linkonce_odr" => Some ( llvm:: LinkOnceODRLinkage ) ,
2174
+ "private" => Some ( llvm:: PrivateLinkage ) ,
2175
+ "weak" => Some ( llvm:: WeakAnyLinkage ) ,
2176
+ "weak_odr" => Some ( llvm:: WeakODRLinkage ) ,
2177
+ _ => None ,
2178
+ }
2179
+ }
2180
+
2181
+
2156
2182
/// Enum describing the origin of an LLVM `Value`, for linkage purposes.
2157
2183
pub enum ValueOrigin {
2158
2184
/// The LLVM `Value` is in this context because the corresponding item was
@@ -2190,6 +2216,23 @@ pub fn update_linkage(ccx: &CrateContext,
2190
2216
OriginalTranslation => { } ,
2191
2217
}
2192
2218
2219
+ match id {
2220
+ Some ( id) => {
2221
+ let item = ccx. tcx ( ) . map . get ( id) ;
2222
+ if let ast_map:: NodeItem ( i) = item {
2223
+ if let Some ( name) = attr:: first_attr_value_str_by_name ( i. attrs [ ] , "linkage" ) {
2224
+ if let Some ( linkage) = llvm_linkage_by_name ( name. get ( ) ) {
2225
+ llvm:: SetLinkage ( llval, linkage) ;
2226
+ } else {
2227
+ ccx. sess ( ) . span_fatal ( i. span , "invalid linkage specified" ) ;
2228
+ }
2229
+ return ;
2230
+ }
2231
+ }
2232
+ }
2233
+ _ => { }
2234
+ }
2235
+
2193
2236
match id {
2194
2237
Some ( id) if ccx. reachable ( ) . contains ( & id) => {
2195
2238
llvm:: SetLinkage ( llval, llvm:: ExternalLinkage ) ;
0 commit comments