Skip to content

Commit 368e586

Browse files
committed
Add linkage to TransFnAttrs
Part of #47320
1 parent 07890c5 commit 368e586

File tree

7 files changed

+48
-54
lines changed

7 files changed

+48
-54
lines changed

src/librustc/hir/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ pub use self::Visibility::{Public, Inherited};
3030
use hir::def::Def;
3131
use hir::def_id::{DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX};
3232
use util::nodemap::{NodeMap, FxHashSet};
33+
use mir::mono::Linkage;
3334

3435
use syntax_pos::{Span, DUMMY_SP};
3536
use syntax::codemap::{self, Spanned};
@@ -2218,6 +2219,7 @@ pub struct TransFnAttrs {
22182219
pub inline: InlineAttr,
22192220
pub export_name: Option<Symbol>,
22202221
pub target_features: Vec<Symbol>,
2222+
pub linkage: Option<Linkage>,
22212223
}
22222224

22232225
bitflags! {
@@ -2240,6 +2242,7 @@ impl TransFnAttrs {
22402242
inline: InlineAttr::None,
22412243
export_name: None,
22422244
target_features: vec![],
2245+
linkage: None,
22432246
}
22442247
}
22452248

src/librustc/ich/impls_hir.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1149,12 +1149,14 @@ impl<'hir> HashStable<StableHashingContext<'hir>> for hir::TransFnAttrs
11491149
inline,
11501150
export_name,
11511151
ref target_features,
1152+
linkage,
11521153
} = *self;
11531154

11541155
flags.hash_stable(hcx, hasher);
11551156
inline.hash_stable(hcx, hasher);
11561157
export_name.hash_stable(hcx, hasher);
11571158
target_features.hash_stable(hcx, hasher);
1159+
linkage.hash_stable(hcx, hasher);
11581160
}
11591161
}
11601162

src/librustc/mir/mono.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ pub struct CodegenUnit<'tcx> {
7373
size_estimate: Option<usize>,
7474
}
7575

76-
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
76+
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
7777
pub enum Linkage {
7878
External,
7979
AvailableExternally,

src/librustc_mir/monomorphize/item.rs

Lines changed: 3 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -21,41 +21,14 @@ use rustc::session::config::OptLevel;
2121
use rustc::ty::{self, Ty, TyCtxt};
2222
use rustc::ty::subst::Substs;
2323
use syntax::ast;
24-
use syntax::attr::{self, InlineAttr};
24+
use syntax::attr::InlineAttr;
2525
use std::fmt::{self, Write};
2626
use std::iter;
2727
use rustc::mir::mono::Linkage;
2828
use syntax_pos::symbol::Symbol;
2929
use syntax::codemap::Span;
3030
pub use rustc::mir::mono::MonoItem;
3131

32-
pub fn linkage_by_name(name: &str) -> Option<Linkage> {
33-
use rustc::mir::mono::Linkage::*;
34-
35-
// Use the names from src/llvm/docs/LangRef.rst here. Most types are only
36-
// applicable to variable declarations and may not really make sense for
37-
// Rust code in the first place but whitelist them anyway and trust that
38-
// the user knows what s/he's doing. Who knows, unanticipated use cases
39-
// may pop up in the future.
40-
//
41-
// ghost, dllimport, dllexport and linkonce_odr_autohide are not supported
42-
// and don't have to be, LLVM treats them as no-ops.
43-
match name {
44-
"appending" => Some(Appending),
45-
"available_externally" => Some(AvailableExternally),
46-
"common" => Some(Common),
47-
"extern_weak" => Some(ExternalWeak),
48-
"external" => Some(External),
49-
"internal" => Some(Internal),
50-
"linkonce" => Some(LinkOnceAny),
51-
"linkonce_odr" => Some(LinkOnceODR),
52-
"private" => Some(Private),
53-
"weak" => Some(WeakAny),
54-
"weak_odr" => Some(WeakODR),
55-
_ => None,
56-
}
57-
}
58-
5932
/// Describes how a translation item will be instantiated in object files.
6033
#[derive(PartialEq, Eq, Clone, Copy, Debug, Hash)]
6134
pub enum InstantiationMode {
@@ -164,21 +137,8 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug {
164137
MonoItem::GlobalAsm(..) => return None,
165138
};
166139

167-
let attributes = tcx.get_attrs(def_id);
168-
if let Some(name) = attr::first_attr_value_str_by_name(&attributes, "linkage") {
169-
if let Some(linkage) = linkage_by_name(&name.as_str()) {
170-
Some(linkage)
171-
} else {
172-
let span = tcx.hir.span_if_local(def_id);
173-
if let Some(span) = span {
174-
tcx.sess.span_fatal(span, "invalid linkage specified")
175-
} else {
176-
tcx.sess.fatal(&format!("invalid linkage specified: {}", name))
177-
}
178-
}
179-
} else {
180-
None
181-
}
140+
let trans_fn_attrs = tcx.trans_fn_attrs(def_id);
141+
trans_fn_attrs.linkage
182142
}
183143

184144
/// Returns whether this instance is instantiable - whether it has no unsatisfied

src/librustc_trans/base.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,6 @@ use syntax::ast;
9090
use mir::operand::OperandValue;
9191

9292
pub use rustc_trans_utils::check_for_rustc_errors_attr;
93-
pub use rustc_mir::monomorphize::item::linkage_by_name;
9493

9594
pub struct StatRecorder<'a, 'tcx: 'a> {
9695
cx: &'a CodegenCx<'a, 'tcx>,

src/librustc_trans/consts.rs

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -146,20 +146,12 @@ pub fn get_static(cx: &CodegenCx, def_id: DefId) -> ValueRef {
146146
hir_map::NodeForeignItem(&hir::ForeignItem {
147147
ref attrs, span, node: hir::ForeignItemStatic(..), ..
148148
}) => {
149-
150-
let g = if let Some(name) =
151-
attr::first_attr_value_str_by_name(&attrs, "linkage") {
149+
let g = if let Some(linkage) = cx.tcx.trans_fn_attrs(def_id).linkage {
152150
// If this is a static with a linkage specified, then we need to handle
153151
// it a little specially. The typesystem prevents things like &T and
154152
// extern "C" fn() from being non-null, so we can't just declare a
155153
// static and call it a day. Some linkages (like weak) will make it such
156154
// that the static actually has a null value.
157-
let linkage = match base::linkage_by_name(&name.as_str()) {
158-
Some(linkage) => linkage,
159-
None => {
160-
cx.sess().span_fatal(span, "invalid linkage specified");
161-
}
162-
};
163155
let llty2 = match ty.sty {
164156
ty::TyRawPtr(ref mt) => cx.layout_of(mt.ty).llvm_type(cx),
165157
_ => {

src/librustc_typeck/collect.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ use constrained_type_params as ctp;
3030
use middle::lang_items::SizedTraitLangItem;
3131
use middle::const_val::ConstVal;
3232
use middle::resolve_lifetime as rl;
33+
use rustc::mir::mono::Linkage;
3334
use rustc::traits::Reveal;
3435
use rustc::ty::subst::Substs;
3536
use rustc::ty::{ToPredicate, ReprOptions};
@@ -1782,6 +1783,39 @@ fn from_target_feature(
17821783
}
17831784
}
17841785

1786+
fn linkage_by_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId, name: &str) -> Linkage {
1787+
use rustc::mir::mono::Linkage::*;
1788+
1789+
// Use the names from src/llvm/docs/LangRef.rst here. Most types are only
1790+
// applicable to variable declarations and may not really make sense for
1791+
// Rust code in the first place but whitelist them anyway and trust that
1792+
// the user knows what s/he's doing. Who knows, unanticipated use cases
1793+
// may pop up in the future.
1794+
//
1795+
// ghost, dllimport, dllexport and linkonce_odr_autohide are not supported
1796+
// and don't have to be, LLVM treats them as no-ops.
1797+
match name {
1798+
"appending" => Appending,
1799+
"available_externally" => AvailableExternally,
1800+
"common" => Common,
1801+
"extern_weak" => ExternalWeak,
1802+
"external" => External,
1803+
"internal" => Internal,
1804+
"linkonce" => LinkOnceAny,
1805+
"linkonce_odr" => LinkOnceODR,
1806+
"private" => Private,
1807+
"weak" => WeakAny,
1808+
"weak_odr" => WeakODR,
1809+
_ => {
1810+
let span = tcx.hir.span_if_local(def_id);
1811+
if let Some(span) = span {
1812+
tcx.sess.span_fatal(span, "invalid linkage specified")
1813+
} else {
1814+
tcx.sess.fatal(&format!("invalid linkage specified: {}", name))
1815+
}
1816+
}
1817+
}
1818+
}
17851819

17861820
fn trans_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> TransFnAttrs {
17871821
let attrs = tcx.get_attrs(id);
@@ -1868,6 +1902,10 @@ fn trans_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> TransFnAt
18681902
tcx.sess.span_err(attr.span, msg);
18691903
}
18701904
from_target_feature(tcx, attr, &whitelist, &mut trans_fn_attrs.target_features);
1905+
} else if attr.check_name("linkage") {
1906+
if let Some(val) = attr.value_str() {
1907+
trans_fn_attrs.linkage = Some(linkage_by_name(tcx, id, &val.as_str()));
1908+
}
18711909
}
18721910
}
18731911

0 commit comments

Comments
 (0)