Skip to content

Commit

Permalink
Allow for instantiating statics from upstream crates.
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelwoerister committed Feb 19, 2018
1 parent 1be7f96 commit 89b3ef3
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 28 deletions.
15 changes: 11 additions & 4 deletions src/librustc_trans/consts.rs
Expand Up @@ -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
Expand All @@ -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 {
Expand Down Expand Up @@ -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);
}
Expand Down
40 changes: 16 additions & 24 deletions src/librustc_trans/trans_item.rs
Expand Up @@ -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;
Expand All @@ -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);
Expand Down Expand Up @@ -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))
});

Expand Down

0 comments on commit 89b3ef3

Please sign in to comment.