mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-11 16:15:03 +00:00
Allow for instantiating statics from upstream crates.
This commit is contained in:
parent
1be7f966e0
commit
89b3ef3e8e
@ -226,8 +226,15 @@ pub fn get_static(cx: &CodegenCx, def_id: DefId) -> ValueRef {
|
||||
// statically in the final application, we always mark such symbols as 'dllimport'.
|
||||
// If final linkage happens to be static, we rely on compiler-emitted __imp_ stubs to
|
||||
// make things work.
|
||||
unsafe {
|
||||
llvm::LLVMSetDLLStorageClass(g, llvm::DLLStorageClass::DllImport);
|
||||
//
|
||||
// However, in some scenarios we defer emission of statics to downstream
|
||||
// crates, so there are cases where a static with an upstream DefId
|
||||
// is actually present in the current crate. We can find out via the
|
||||
// is_translated_item query.
|
||||
if !cx.tcx.is_translated_item(def_id) {
|
||||
unsafe {
|
||||
llvm::LLVMSetDLLStorageClass(g, llvm::DLLStorageClass::DllImport);
|
||||
}
|
||||
}
|
||||
}
|
||||
g
|
||||
@ -246,8 +253,8 @@ pub fn get_static(cx: &CodegenCx, def_id: DefId) -> ValueRef {
|
||||
}
|
||||
|
||||
pub fn trans_static<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
||||
m: hir::Mutability,
|
||||
def_id: DefId,
|
||||
is_mutable: bool,
|
||||
attrs: &[ast::Attribute])
|
||||
-> Result<ValueRef, ConstEvalErr<'tcx>> {
|
||||
unsafe {
|
||||
@ -298,7 +305,7 @@ pub fn trans_static<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
||||
|
||||
// As an optimization, all shared statics which do not have interior
|
||||
// mutability are placed into read-only memory.
|
||||
if m != hir::MutMutable {
|
||||
if !is_mutable {
|
||||
if cx.type_is_freeze(ty) {
|
||||
llvm::LLVMSetGlobalConstant(g, llvm::True);
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ use llvm;
|
||||
use monomorphize::Instance;
|
||||
use type_of::LayoutLlvmExt;
|
||||
use rustc::hir;
|
||||
use rustc::hir::def::Def;
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::mir::mono::{Linkage, Visibility};
|
||||
use rustc::ty::TypeFoldable;
|
||||
@ -46,24 +47,23 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> {
|
||||
match *self.as_mono_item() {
|
||||
MonoItem::Static(def_id) => {
|
||||
let tcx = cx.tcx;
|
||||
let node_id = match tcx.hir.as_local_node_id(def_id) {
|
||||
Some(node_id) => node_id,
|
||||
let is_mutable = match tcx.describe_def(def_id) {
|
||||
Some(Def::Static(_, is_mutable)) => is_mutable,
|
||||
Some(other) => {
|
||||
bug!("Expected Def::Static, found {:?}", other)
|
||||
}
|
||||
None => {
|
||||
bug!("MonoItemExt::define() called for non-local \
|
||||
static `{:?}`.", def_id)
|
||||
bug!("Expected Def::Static for {:?}, found nothing", def_id)
|
||||
}
|
||||
};
|
||||
let attrs = tcx.get_attrs(def_id);
|
||||
|
||||
match consts::trans_static(&cx, def_id, is_mutable, &attrs) {
|
||||
Ok(_) => { /* Cool, everything's alright. */ },
|
||||
Err(err) => {
|
||||
err.report(tcx, tcx.def_span(def_id), "static");
|
||||
}
|
||||
};
|
||||
let item = tcx.hir.expect_item(node_id);
|
||||
if let hir::ItemStatic(_, m, _) = item.node {
|
||||
match consts::trans_static(&cx, m, def_id, &item.attrs) {
|
||||
Ok(_) => { /* Cool, everything's alright. */ },
|
||||
Err(err) => {
|
||||
err.report(tcx, item.span, "static");
|
||||
}
|
||||
};
|
||||
} else {
|
||||
span_bug!(item.span, "Mismatch between hir::Item type and TransItem type")
|
||||
}
|
||||
}
|
||||
MonoItem::GlobalAsm(node_id) => {
|
||||
let item = cx.tcx.hir.expect_item(node_id);
|
||||
@ -137,20 +137,12 @@ fn predefine_static<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
||||
linkage: Linkage,
|
||||
visibility: Visibility,
|
||||
symbol_name: &str) {
|
||||
let node_id = match cx.tcx.hir.as_local_node_id(def_id) {
|
||||
Some(node_id) => node_id,
|
||||
None => {
|
||||
bug!("MonoItemExt::predefine() called for non-local static `{:?}`.",
|
||||
def_id)
|
||||
}
|
||||
};
|
||||
|
||||
let instance = Instance::mono(cx.tcx, def_id);
|
||||
let ty = instance.ty(cx.tcx);
|
||||
let llty = cx.layout_of(ty).llvm_type(cx);
|
||||
|
||||
let g = declare::define_global(cx, symbol_name, llty).unwrap_or_else(|| {
|
||||
cx.sess().span_fatal(cx.tcx.hir.span(node_id),
|
||||
cx.sess().span_fatal(cx.tcx.def_span(def_id),
|
||||
&format!("symbol `{}` is already defined", symbol_name))
|
||||
});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user