diff options
| author | Jakub Bukaj <jakub@jakub.cc> | 2014-11-18 00:23:50 +0100 |
|---|---|---|
| committer | Jakub Bukaj <jakub@jakub.cc> | 2014-11-18 00:23:50 +0100 |
| commit | fcf9fb61574a415653fa0c787058972312ce1235 (patch) | |
| tree | b1118890b3dbea75a886d0dc14abd4ba5e7b2ed0 /src/librustc | |
| parent | f09279395b6ca40f1398277971586197f949738a (diff) | |
| parent | 33893aebcf19f6bf7e0102406117afa34a955425 (diff) | |
| download | rust-fcf9fb61574a415653fa0c787058972312ce1235.tar.gz rust-fcf9fb61574a415653fa0c787058972312ce1235.zip | |
rollup merge of #18890: luqmana/tf
This is especially useful for declaring a static with external linkage in an executable. There isn't any way to do that currently since we mark everything in an executable as internal by default. Also, a quick fix to have the no-compiler-rt target option respected when building staticlibs as well.
Diffstat (limited to 'src/librustc')
| -rw-r--r-- | src/librustc/back/link.rs | 4 | ||||
| -rw-r--r-- | src/librustc/lint/builtin.rs | 1 | ||||
| -rw-r--r-- | src/librustc/middle/trans/base.rs | 45 | ||||
| -rw-r--r-- | src/librustc/middle/trans/foreign.rs | 29 |
4 files changed, 50 insertions, 29 deletions
diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index 97ab3209d28..766715ff251 100644 --- a/src/librustc/back/link.rs +++ b/src/librustc/back/link.rs @@ -728,7 +728,9 @@ fn link_staticlib(sess: &Session, obj_filename: &Path, out_filename: &Path) { if sess.target.target.options.morestack { ab.add_native_library("morestack").unwrap(); } - ab.add_native_library("compiler-rt").unwrap(); + if !sess.target.target.options.no_compiler_rt { + ab.add_native_library("compiler-rt").unwrap(); + } let crates = sess.cstore.get_used_crates(cstore::RequireStatic); let mut all_native_libs = vec![]; diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 4247d192d6d..df014eb1206 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -623,6 +623,7 @@ impl LintPass for UnusedAttributes { "link", "link_name", "link_section", + "linkage", "no_builtins", "no_mangle", "no_split_stack", diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index b267d1d7f3e..77ee433e62b 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -36,7 +36,7 @@ use driver::config::{NoDebugInfo, FullDebugInfo}; use driver::driver::{CrateAnalysis, CrateTranslation, ModuleTranslation}; use driver::session::Session; use lint; -use llvm::{BasicBlockRef, ValueRef, Vector, get_param}; +use llvm::{BasicBlockRef, Linkage, ValueRef, Vector, get_param}; use llvm; use metadata::{csearch, encoder, loader}; use middle::astencode; @@ -2137,6 +2137,32 @@ impl<'a, 'tcx, 'v> Visitor<'v> for TransItemVisitor<'a, 'tcx> { } } +pub fn llvm_linkage_by_name(name: &str) -> Option<Linkage> { + // Use the names from src/llvm/docs/LangRef.rst here. Most types are only + // applicable to variable declarations and may not really make sense for + // Rust code in the first place but whitelist them anyway and trust that + // the user knows what s/he's doing. Who knows, unanticipated use cases + // may pop up in the future. + // + // ghost, dllimport, dllexport and linkonce_odr_autohide are not supported + // and don't have to be, LLVM treats them as no-ops. + match name { + "appending" => Some(llvm::AppendingLinkage), + "available_externally" => Some(llvm::AvailableExternallyLinkage), + "common" => Some(llvm::CommonLinkage), + "extern_weak" => Some(llvm::ExternalWeakLinkage), + "external" => Some(llvm::ExternalLinkage), + "internal" => Some(llvm::InternalLinkage), + "linkonce" => Some(llvm::LinkOnceAnyLinkage), + "linkonce_odr" => Some(llvm::LinkOnceODRLinkage), + "private" => Some(llvm::PrivateLinkage), + "weak" => Some(llvm::WeakAnyLinkage), + "weak_odr" => Some(llvm::WeakODRLinkage), + _ => None, + } +} + + /// Enum describing the origin of an LLVM `Value`, for linkage purposes. pub enum ValueOrigin { /// The LLVM `Value` is in this context because the corresponding item was @@ -2175,6 +2201,23 @@ pub fn update_linkage(ccx: &CrateContext, } match id { + Some(id) => { + let item = ccx.tcx().map.get(id); + if let ast_map::NodeItem(i) = item { + if let Some(name) = attr::first_attr_value_str_by_name(i.attrs[], "linkage") { + if let Some(linkage) = llvm_linkage_by_name(name.get()) { + llvm::SetLinkage(llval, linkage); + } else { + ccx.sess().span_fatal(i.span, "invalid linkage specified"); + } + return; + } + } + } + _ => {} + } + + match id { Some(id) if ccx.reachable().contains(&id) => { llvm::SetLinkage(llval, llvm::ExternalLinkage); }, diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index 1afb73b08f7..940319d050b 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -10,10 +10,10 @@ use back::{link}; -use llvm::{ValueRef, CallConv, Linkage, get_param}; +use llvm::{ValueRef, CallConv, get_param}; use llvm; use middle::weak_lang_items; -use middle::trans::base::push_ctxt; +use middle::trans::base::{llvm_linkage_by_name, push_ctxt}; use middle::trans::base; use middle::trans::build::*; use middle::trans::cabi; @@ -101,31 +101,6 @@ pub fn llvm_calling_convention(ccx: &CrateContext, } } -pub fn llvm_linkage_by_name(name: &str) -> Option<Linkage> { - // Use the names from src/llvm/docs/LangRef.rst here. Most types are only - // applicable to variable declarations and may not really make sense for - // Rust code in the first place but whitelist them anyway and trust that - // the user knows what s/he's doing. Who knows, unanticipated use cases - // may pop up in the future. - // - // ghost, dllimport, dllexport and linkonce_odr_autohide are not supported - // and don't have to be, LLVM treats them as no-ops. - match name { - "appending" => Some(llvm::AppendingLinkage), - "available_externally" => Some(llvm::AvailableExternallyLinkage), - "common" => Some(llvm::CommonLinkage), - "extern_weak" => Some(llvm::ExternalWeakLinkage), - "external" => Some(llvm::ExternalLinkage), - "internal" => Some(llvm::InternalLinkage), - "linkonce" => Some(llvm::LinkOnceAnyLinkage), - "linkonce_odr" => Some(llvm::LinkOnceODRLinkage), - "private" => Some(llvm::PrivateLinkage), - "weak" => Some(llvm::WeakAnyLinkage), - "weak_odr" => Some(llvm::WeakODRLinkage), - _ => None, - } -} - pub fn register_static(ccx: &CrateContext, foreign_item: &ast::ForeignItem) -> ValueRef { let ty = ty::node_id_to_type(ccx.tcx(), foreign_item.id); |
