提交 368e586a 编写于 作者: W Wesley Wiser

Add linkage to TransFnAttrs

Part of #47320
上级 07890c5c
......@@ -30,6 +30,7 @@
use hir::def::Def;
use hir::def_id::{DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX};
use util::nodemap::{NodeMap, FxHashSet};
use mir::mono::Linkage;
use syntax_pos::{Span, DUMMY_SP};
use syntax::codemap::{self, Spanned};
......@@ -2218,6 +2219,7 @@ pub struct TransFnAttrs {
pub inline: InlineAttr,
pub export_name: Option<Symbol>,
pub target_features: Vec<Symbol>,
pub linkage: Option<Linkage>,
}
bitflags! {
......@@ -2240,6 +2242,7 @@ pub fn new() -> TransFnAttrs {
inline: InlineAttr::None,
export_name: None,
target_features: vec![],
linkage: None,
}
}
......
......@@ -1149,12 +1149,14 @@ fn hash_stable<W: StableHasherResult>(&self,
inline,
export_name,
ref target_features,
linkage,
} = *self;
flags.hash_stable(hcx, hasher);
inline.hash_stable(hcx, hasher);
export_name.hash_stable(hcx, hasher);
target_features.hash_stable(hcx, hasher);
linkage.hash_stable(hcx, hasher);
}
}
......
......@@ -73,7 +73,7 @@ pub struct CodegenUnit<'tcx> {
size_estimate: Option<usize>,
}
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
pub enum Linkage {
External,
AvailableExternally,
......
......@@ -21,7 +21,7 @@
use rustc::ty::{self, Ty, TyCtxt};
use rustc::ty::subst::Substs;
use syntax::ast;
use syntax::attr::{self, InlineAttr};
use syntax::attr::InlineAttr;
use std::fmt::{self, Write};
use std::iter;
use rustc::mir::mono::Linkage;
......@@ -29,33 +29,6 @@
use syntax::codemap::Span;
pub use rustc::mir::mono::MonoItem;
pub fn linkage_by_name(name: &str) -> Option<Linkage> {
use rustc::mir::mono::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(Appending),
"available_externally" => Some(AvailableExternally),
"common" => Some(Common),
"extern_weak" => Some(ExternalWeak),
"external" => Some(External),
"internal" => Some(Internal),
"linkonce" => Some(LinkOnceAny),
"linkonce_odr" => Some(LinkOnceODR),
"private" => Some(Private),
"weak" => Some(WeakAny),
"weak_odr" => Some(WeakODR),
_ => None,
}
}
/// Describes how a translation item will be instantiated in object files.
#[derive(PartialEq, Eq, Clone, Copy, Debug, Hash)]
pub enum InstantiationMode {
......@@ -164,21 +137,8 @@ fn explicit_linkage(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Option<Linkage> {
MonoItem::GlobalAsm(..) => return None,
};
let attributes = tcx.get_attrs(def_id);
if let Some(name) = attr::first_attr_value_str_by_name(&attributes, "linkage") {
if let Some(linkage) = linkage_by_name(&name.as_str()) {
Some(linkage)
} else {
let span = tcx.hir.span_if_local(def_id);
if let Some(span) = span {
tcx.sess.span_fatal(span, "invalid linkage specified")
} else {
tcx.sess.fatal(&format!("invalid linkage specified: {}", name))
}
}
} else {
None
}
let trans_fn_attrs = tcx.trans_fn_attrs(def_id);
trans_fn_attrs.linkage
}
/// Returns whether this instance is instantiable - whether it has no unsatisfied
......
......@@ -90,7 +90,6 @@
use mir::operand::OperandValue;
pub use rustc_trans_utils::check_for_rustc_errors_attr;
pub use rustc_mir::monomorphize::item::linkage_by_name;
pub struct StatRecorder<'a, 'tcx: 'a> {
cx: &'a CodegenCx<'a, 'tcx>,
......
......@@ -146,20 +146,12 @@ pub fn get_static(cx: &CodegenCx, def_id: DefId) -> ValueRef {
hir_map::NodeForeignItem(&hir::ForeignItem {
ref attrs, span, node: hir::ForeignItemStatic(..), ..
}) => {
let g = if let Some(name) =
attr::first_attr_value_str_by_name(&attrs, "linkage") {
let g = if let Some(linkage) = cx.tcx.trans_fn_attrs(def_id).linkage {
// If this is a static with a linkage specified, then we need to handle
// it a little specially. The typesystem prevents things like &T and
// extern "C" fn() from being non-null, so we can't just declare a
// static and call it a day. Some linkages (like weak) will make it such
// that the static actually has a null value.
let linkage = match base::linkage_by_name(&name.as_str()) {
Some(linkage) => linkage,
None => {
cx.sess().span_fatal(span, "invalid linkage specified");
}
};
let llty2 = match ty.sty {
ty::TyRawPtr(ref mt) => cx.layout_of(mt.ty).llvm_type(cx),
_ => {
......
......@@ -30,6 +30,7 @@
use middle::lang_items::SizedTraitLangItem;
use middle::const_val::ConstVal;
use middle::resolve_lifetime as rl;
use rustc::mir::mono::Linkage;
use rustc::traits::Reveal;
use rustc::ty::subst::Substs;
use rustc::ty::{ToPredicate, ReprOptions};
......@@ -1782,6 +1783,39 @@ fn from_target_feature(
}
}
fn linkage_by_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId, name: &str) -> Linkage {
use rustc::mir::mono::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" => Appending,
"available_externally" => AvailableExternally,
"common" => Common,
"extern_weak" => ExternalWeak,
"external" => External,
"internal" => Internal,
"linkonce" => LinkOnceAny,
"linkonce_odr" => LinkOnceODR,
"private" => Private,
"weak" => WeakAny,
"weak_odr" => WeakODR,
_ => {
let span = tcx.hir.span_if_local(def_id);
if let Some(span) = span {
tcx.sess.span_fatal(span, "invalid linkage specified")
} else {
tcx.sess.fatal(&format!("invalid linkage specified: {}", name))
}
}
}
}
fn trans_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> TransFnAttrs {
let attrs = tcx.get_attrs(id);
......@@ -1868,6 +1902,10 @@ fn trans_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> TransFnAt
tcx.sess.span_err(attr.span, msg);
}
from_target_feature(tcx, attr, &whitelist, &mut trans_fn_attrs.target_features);
} else if attr.check_name("linkage") {
if let Some(val) = attr.value_str() {
trans_fn_attrs.linkage = Some(linkage_by_name(tcx, id, &val.as_str()));
}
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册