Rollup merge of #48353 - michaelwoerister:monoitem-static-defid, r=eddyb

Allow for instantiating statics from upstream crates

This PR makes the infrastructure around translating statics a bit more flexible so that it can also instantiate statics from upstream crates if the need arises. This is preparatory work for a MIR-only RLIBs prototype, where the instantiation of a `static` may be deferred until a leaf crate.

r? @eddyb (feel free to assign to someone else if you're busy)
This commit is contained in:
Manish Goregaokar 2018-02-24 08:55:51 -08:00
commit 2483d842fb
18 changed files with 204 additions and 90 deletions

View File

@ -625,7 +625,7 @@ define_dep_nodes!( <'tcx>
[eval_always] CollectAndPartitionTranslationItems,
[] ExportName(DefId),
[] ContainsExternIndicator(DefId),
[] IsTranslatedFunction(DefId),
[] IsTranslatedItem(DefId),
[] CodegenUnit(InternedString),
[] CompileCodegenUnit(InternedString),
[input] OutputFilenames,

View File

@ -22,6 +22,7 @@ use hir::def_id::{CRATE_DEF_INDEX, DefId, LocalDefId, DefIndexAddressSpace};
use syntax::abi::Abi;
use syntax::ast::{self, Name, NodeId, CRATE_NODE_ID};
use syntax::codemap::Spanned;
use syntax::ext::base::MacroKind;
use syntax_pos::Span;
use hir::*;
@ -32,6 +33,7 @@ use util::nodemap::{DefIdMap, FxHashMap};
use arena::TypedArena;
use std::cell::RefCell;
use std::io;
use ty::TyCtxt;
pub mod blocks;
mod collector;
@ -39,6 +41,7 @@ mod def_collector;
pub mod definitions;
mod hir_id_validator;
pub const ITEM_LIKE_SPACE: DefIndexAddressSpace = DefIndexAddressSpace::Low;
pub const REGULAR_SPACE: DefIndexAddressSpace = DefIndexAddressSpace::High;
@ -373,6 +376,92 @@ impl<'hir> Map<'hir> {
self.definitions.as_local_node_id(def_id.to_def_id()).unwrap()
}
pub fn describe_def(&self, node_id: NodeId) -> Option<Def> {
let node = if let Some(node) = self.find(node_id) {
node
} else {
return None
};
match node {
NodeItem(item) => {
let def_id = || {
self.local_def_id(item.id)
};
match item.node {
ItemStatic(_, m, _) => Some(Def::Static(def_id(),
m == MutMutable)),
ItemConst(..) => Some(Def::Const(def_id())),
ItemFn(..) => Some(Def::Fn(def_id())),
ItemMod(..) => Some(Def::Mod(def_id())),
ItemGlobalAsm(..) => Some(Def::GlobalAsm(def_id())),
ItemTy(..) => Some(Def::TyAlias(def_id())),
ItemEnum(..) => Some(Def::Enum(def_id())),
ItemStruct(..) => Some(Def::Struct(def_id())),
ItemUnion(..) => Some(Def::Union(def_id())),
ItemTrait(..) => Some(Def::Trait(def_id())),
ItemTraitAlias(..) => {
bug!("trait aliases are not yet implemented (see issue #41517)")
},
ItemExternCrate(_) |
ItemUse(..) |
ItemForeignMod(..) |
ItemImpl(..) => None,
}
}
NodeForeignItem(item) => {
let def_id = self.local_def_id(item.id);
match item.node {
ForeignItemFn(..) => Some(Def::Fn(def_id)),
ForeignItemStatic(_, m) => Some(Def::Static(def_id, m)),
ForeignItemType => Some(Def::TyForeign(def_id)),
}
}
NodeTraitItem(item) => {
let def_id = self.local_def_id(item.id);
match item.node {
TraitItemKind::Const(..) => Some(Def::AssociatedConst(def_id)),
TraitItemKind::Method(..) => Some(Def::Method(def_id)),
TraitItemKind::Type(..) => Some(Def::AssociatedTy(def_id)),
}
}
NodeImplItem(item) => {
let def_id = self.local_def_id(item.id);
match item.node {
ImplItemKind::Const(..) => Some(Def::AssociatedConst(def_id)),
ImplItemKind::Method(..) => Some(Def::Method(def_id)),
ImplItemKind::Type(..) => Some(Def::AssociatedTy(def_id)),
}
}
NodeVariant(variant) => {
let def_id = self.local_def_id(variant.node.data.id());
Some(Def::Variant(def_id))
}
NodeField(_) |
NodeExpr(_) |
NodeStmt(_) |
NodeTy(_) |
NodeTraitRef(_) |
NodePat(_) |
NodeBinding(_) |
NodeStructCtor(_) |
NodeLifetime(_) |
NodeVisibility(_) |
NodeBlock(_) => None,
NodeLocal(local) => {
Some(Def::Local(local.id))
}
NodeMacroDef(macro_def) => {
Some(Def::Macro(self.local_def_id(macro_def.id),
MacroKind::Bang))
}
NodeTyParam(param) => {
Some(Def::TyParam(self.local_def_id(param.id)))
}
}
}
fn entry_count(&self) -> usize {
self.map.len()
}
@ -1275,3 +1364,12 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String {
}
}
}
pub fn describe_def(tcx: TyCtxt, def_id: DefId) -> Option<Def> {
if let Some(node_id) = tcx.hir.as_local_node_id(def_id) {
tcx.hir.describe_def(node_id)
} else {
bug!("Calling local describe_def query provider for upstream DefId: {:?}",
def_id)
}
}

View File

@ -43,6 +43,7 @@ use syntax::tokenstream::TokenStream;
use syntax::util::ThinVec;
use syntax::util::parser::ExprPrecedence;
use ty::AdtKind;
use ty::maps::Providers;
use rustc_data_structures::indexed_vec;
@ -2204,3 +2205,8 @@ pub type TraitMap = NodeMap<Vec<TraitCandidate>>;
// Map from the NodeId of a glob import to a list of items which are actually
// imported.
pub type GlobMap = NodeMap<FxHashSet<Name>>;
pub fn provide(providers: &mut Providers) {
providers.describe_def = map::describe_def;
}

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use hir::def_id::DefId;
use syntax::ast::NodeId;
use syntax::symbol::InternedString;
use ty::{Instance, TyCtxt};
@ -21,7 +22,7 @@ use std::hash::Hash;
#[derive(PartialEq, Eq, Clone, Copy, Debug, Hash)]
pub enum MonoItem<'tcx> {
Fn(Instance<'tcx>),
Static(NodeId),
Static(DefId),
GlobalAsm(NodeId),
}
@ -50,7 +51,9 @@ impl<'tcx> HashStable<StableHashingContext<'tcx>> for MonoItem<'tcx> {
MonoItem::Fn(ref instance) => {
instance.hash_stable(hcx, hasher);
}
MonoItem::Static(node_id) |
MonoItem::Static(def_id) => {
def_id.hash_stable(hcx, hasher);
}
MonoItem::GlobalAsm(node_id) => {
hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
node_id.hash_stable(hcx, hasher);

View File

@ -349,7 +349,7 @@ define_maps! { <'tcx>
[] fn export_name: ExportName(DefId) -> Option<Symbol>,
[] fn contains_extern_indicator: ContainsExternIndicator(DefId) -> bool,
[] fn symbol_export_level: GetSymbolExportLevel(DefId) -> SymbolExportLevel,
[] fn is_translated_function: IsTranslatedFunction(DefId) -> bool,
[] fn is_translated_item: IsTranslatedItem(DefId) -> bool,
[] fn codegen_unit: CodegenUnit(InternedString) -> Arc<CodegenUnit<'tcx>>,
[] fn compile_codegen_unit: CompileCodegenUnit(InternedString) -> Stats,
[] fn output_filenames: output_filenames_node(CrateNum)

View File

@ -929,7 +929,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
DepKind::ContainsExternIndicator => {
force!(contains_extern_indicator, def_id!());
}
DepKind::IsTranslatedFunction => { force!(is_translated_function, def_id!()); }
DepKind::IsTranslatedItem => { force!(is_translated_item, def_id!()); }
DepKind::OutputFilenames => { force!(output_filenames, LOCAL_CRATE); }
DepKind::TargetFeaturesWhitelist => { force!(target_features_whitelist, LOCAL_CRATE); }

View File

@ -932,6 +932,7 @@ pub fn phase_2_configure_and_expand_inner<'a, F>(sess: &'a Session,
}
pub fn default_provide(providers: &mut ty::maps::Providers) {
hir::provide(providers);
borrowck::provide(providers);
mir::provide(providers);
reachable::provide(providers);

View File

@ -368,8 +368,7 @@ fn collect_items_rec<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let recursion_depth_reset;
match starting_point {
MonoItem::Static(node_id) => {
let def_id = tcx.hir.local_def_id(node_id);
MonoItem::Static(def_id) => {
let instance = Instance::mono(tcx, def_id);
// Sanity check whether this ended up being collected accidentally
@ -652,8 +651,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
let tcx = self.tcx;
let instance = Instance::mono(tcx, static_.def_id);
if should_monomorphize_locally(tcx, &instance) {
let node_id = tcx.hir.as_local_node_id(static_.def_id).unwrap();
self.output.push(MonoItem::Static(node_id));
self.output.push(MonoItem::Static(static_.def_id));
}
self.super_static(static_, context, location);
@ -946,10 +944,10 @@ impl<'b, 'a, 'v> ItemLikeVisitor<'v> for RootCollector<'b, 'a, 'v> {
self.output.push(MonoItem::GlobalAsm(item.id));
}
hir::ItemStatic(..) => {
let def_id = self.tcx.hir.local_def_id(item.id);
debug!("RootCollector: ItemStatic({})",
def_id_to_string(self.tcx,
self.tcx.hir.local_def_id(item.id)));
self.output.push(MonoItem::Static(item.id));
def_id_to_string(self.tcx, def_id));
self.output.push(MonoItem::Static(def_id));
}
hir::ItemConst(..) => {
// const items only generate mono items if they are

View File

@ -97,8 +97,7 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug {
fn symbol_name(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> ty::SymbolName {
match *self.as_mono_item() {
MonoItem::Fn(instance) => tcx.symbol_name(instance),
MonoItem::Static(node_id) => {
let def_id = tcx.hir.local_def_id(node_id);
MonoItem::Static(def_id) => {
tcx.symbol_name(Instance::mono(tcx, def_id))
}
MonoItem::GlobalAsm(node_id) => {
@ -159,7 +158,7 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug {
fn explicit_linkage(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Option<Linkage> {
let def_id = match *self.as_mono_item() {
MonoItem::Fn(ref instance) => instance.def_id(),
MonoItem::Static(node_id) => tcx.hir.local_def_id(node_id),
MonoItem::Static(def_id) => def_id,
MonoItem::GlobalAsm(..) => return None,
};
@ -209,7 +208,7 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug {
debug!("is_instantiable({:?})", self);
let (def_id, substs) = match *self.as_mono_item() {
MonoItem::Fn(ref instance) => (instance.def_id(), instance.substs),
MonoItem::Static(node_id) => (tcx.hir.local_def_id(node_id), Substs::empty()),
MonoItem::Static(def_id) => (def_id, Substs::empty()),
// global asm never has predicates
MonoItem::GlobalAsm(..) => return true
};
@ -218,14 +217,11 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug {
}
fn to_string(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> String {
let hir_map = &tcx.hir;
return match *self.as_mono_item() {
MonoItem::Fn(instance) => {
to_string_internal(tcx, "fn ", instance)
},
MonoItem::Static(node_id) => {
let def_id = hir_map.local_def_id(node_id);
MonoItem::Static(def_id) => {
let instance = Instance::new(def_id, tcx.intern_substs(&[]));
to_string_internal(tcx, "static ", instance)
},
@ -251,7 +247,9 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug {
MonoItem::Fn(Instance { def, .. }) => {
tcx.hir.as_local_node_id(def.def_id())
}
MonoItem::Static(node_id) |
MonoItem::Static(def_id) => {
tcx.hir.as_local_node_id(def_id)
}
MonoItem::GlobalAsm(node_id) => {
Some(node_id)
}

View File

@ -180,7 +180,9 @@ pub trait CodegenUnitExt<'tcx> {
}
}
}
MonoItem::Static(node_id) |
MonoItem::Static(def_id) => {
tcx.hir.as_local_node_id(def_id)
}
MonoItem::GlobalAsm(node_id) => {
Some(node_id)
}
@ -382,7 +384,15 @@ fn place_root_translation_items<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
};
(Linkage::External, visibility)
}
MonoItem::Static(node_id) |
MonoItem::Static(def_id) => {
let visibility = if tcx.is_exported_symbol(def_id) {
can_be_internalized = false;
default_visibility(def_id)
} else {
Visibility::Hidden
};
(Linkage::External, visibility)
}
MonoItem::GlobalAsm(node_id) => {
let def_id = tcx.hir.local_def_id(node_id);
let visibility = if tcx.is_exported_symbol(def_id) {
@ -643,7 +653,7 @@ fn characteristic_def_id_of_trans_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
Some(def_id)
}
MonoItem::Static(node_id) |
MonoItem::Static(def_id) => Some(def_id),
MonoItem::GlobalAsm(node_id) => Some(tcx.hir.local_def_id(node_id)),
}
}

View File

@ -1004,6 +1004,7 @@ fn collect_and_partition_translation_items<'a, 'tcx>(
let translation_items: DefIdSet = items.iter().filter_map(|trans_item| {
match *trans_item {
MonoItem::Fn(ref instance) => Some(instance.def_id()),
MonoItem::Static(def_id) => Some(def_id),
_ => None,
}
}).collect();
@ -1107,7 +1108,7 @@ impl CrateInfo {
}
}
fn is_translated_function(tcx: TyCtxt, id: DefId) -> bool {
fn is_translated_item(tcx: TyCtxt, id: DefId) -> bool {
let (all_trans_items, _) =
tcx.collect_and_partition_translation_items(LOCAL_CRATE);
all_trans_items.contains(&id)
@ -1222,7 +1223,7 @@ pub fn provide(providers: &mut Providers) {
providers.collect_and_partition_translation_items =
collect_and_partition_translation_items;
providers.is_translated_function = is_translated_function;
providers.is_translated_item = is_translated_item;
providers.codegen_unit = |tcx, name| {
let (_, all) = tcx.collect_and_partition_translation_items(LOCAL_CRATE);

View File

@ -149,7 +149,7 @@ pub fn get_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
unsafe {
llvm::LLVMRustSetLinkage(llfn, llvm::Linkage::ExternalLinkage);
if cx.tcx.is_translated_function(instance_def_id) {
if cx.tcx.is_translated_item(instance_def_id) {
if instance_def_id.is_local() {
if !cx.tcx.is_exported_symbol(instance_def_id) {
llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden);

View File

@ -16,7 +16,7 @@ use rustc::hir::map as hir_map;
use rustc::middle::const_val::ConstEvalErr;
use debuginfo;
use base;
use monomorphize::{MonoItem, MonoItemExt};
use monomorphize::MonoItem;
use common::{CodegenCx, val_ty};
use declare;
use monomorphize::Instance;
@ -110,7 +110,17 @@ pub fn get_static(cx: &CodegenCx, def_id: DefId) -> ValueRef {
return g;
}
let defined_in_current_codegen_unit = cx.codegen_unit
.items()
.contains_key(&MonoItem::Static(def_id));
assert!(!defined_in_current_codegen_unit,
"consts::get_static() should always hit the cache for \
statics defined in the same CGU, but did not for `{:?}`",
def_id);
let ty = instance.ty(cx.tcx);
let sym = cx.tcx.symbol_name(instance);
let g = if let Some(id) = cx.tcx.hir.as_local_node_id(def_id) {
let llty = cx.layout_of(ty).llvm_type(cx);
@ -118,13 +128,6 @@ pub fn get_static(cx: &CodegenCx, def_id: DefId) -> ValueRef {
hir_map::NodeItem(&hir::Item {
ref attrs, span, node: hir::ItemStatic(..), ..
}) => {
let sym = MonoItem::Static(id).symbol_name(cx.tcx);
let defined_in_current_codegen_unit = cx.codegen_unit
.items()
.contains_key(&MonoItem::Static(id));
assert!(!defined_in_current_codegen_unit);
if declare::get_declared_value(cx, &sym[..]).is_some() {
span_bug!(span, "trans: Conflicting symbol names for static?");
}
@ -143,7 +146,7 @@ pub fn get_static(cx: &CodegenCx, def_id: DefId) -> ValueRef {
hir_map::NodeForeignItem(&hir::ForeignItem {
ref attrs, span, node: hir::ForeignItemStatic(..), ..
}) => {
let sym = cx.tcx.symbol_name(instance);
let g = if let Some(name) =
attr::first_attr_value_str_by_name(&attrs, "linkage") {
// If this is a static with a linkage specified, then we need to handle
@ -203,8 +206,6 @@ pub fn get_static(cx: &CodegenCx, def_id: DefId) -> ValueRef {
g
} else {
let sym = cx.tcx.symbol_name(instance);
// FIXME(nagisa): perhaps the map of externs could be offloaded to llvm somehow?
// FIXME(nagisa): investigate whether it can be changed into define_global
let g = declare::declare_global(cx, &sym, cx.layout_of(ty).llvm_type(cx));
@ -225,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
@ -245,12 +253,11 @@ pub fn get_static(cx: &CodegenCx, def_id: DefId) -> ValueRef {
}
pub fn trans_static<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
m: hir::Mutability,
id: ast::NodeId,
def_id: DefId,
is_mutable: bool,
attrs: &[ast::Attribute])
-> Result<ValueRef, ConstEvalErr<'tcx>> {
unsafe {
let def_id = cx.tcx.hir.local_def_id(id);
let g = get_static(cx, def_id);
let v = ::mir::trans_static_initializer(cx, def_id)?;
@ -298,13 +305,13 @@ 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);
}
}
debuginfo::create_global_var_metadata(cx, id, g);
debuginfo::create_global_var_metadata(cx, def_id, g);
if attr::contains_name(attrs, "thread_local") {
llvm::set_thread_local_mode(g, cx.tls_model);

View File

@ -14,7 +14,7 @@ use self::EnumDiscriminantInfo::*;
use super::utils::{debug_context, DIB, span_start,
get_namespace_for_item, create_DIArray, is_node_local_to_unit};
use super::namespace::mangled_name_of_item;
use super::namespace::mangled_name_of_instance;
use super::type_names::compute_debuginfo_type_name;
use super::{CrateDebugContext};
use abi;
@ -1634,19 +1634,18 @@ fn create_union_stub<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
///
/// Adds the created metadata nodes directly to the crate's IR.
pub fn create_global_var_metadata(cx: &CodegenCx,
node_id: ast::NodeId,
def_id: DefId,
global: ValueRef) {
if cx.dbg_cx.is_none() {
return;
}
let tcx = cx.tcx;
let node_def_id = tcx.hir.local_def_id(node_id);
let no_mangle = attr::contains_name(&tcx.get_attrs(node_def_id), "no_mangle");
let no_mangle = attr::contains_name(&tcx.get_attrs(def_id), "no_mangle");
// We may want to remove the namespace scope if we're in an extern block, see:
// https://github.com/rust-lang/rust/pull/46457#issuecomment-351750952
let var_scope = get_namespace_for_item(cx, node_def_id);
let span = cx.tcx.def_span(node_def_id);
let var_scope = get_namespace_for_item(cx, def_id);
let span = cx.tcx.def_span(def_id);
let (file_metadata, line_number) = if span != syntax_pos::DUMMY_SP {
let loc = span_start(cx, span);
@ -1655,15 +1654,15 @@ pub fn create_global_var_metadata(cx: &CodegenCx,
(unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER)
};
let is_local_to_unit = is_node_local_to_unit(cx, node_id);
let variable_type = Instance::mono(cx.tcx, node_def_id).ty(cx.tcx);
let is_local_to_unit = is_node_local_to_unit(cx, def_id);
let variable_type = Instance::mono(cx.tcx, def_id).ty(cx.tcx);
let type_metadata = type_metadata(cx, variable_type, span);
let var_name = tcx.item_name(node_def_id).to_string();
let var_name = tcx.item_name(def_id).to_string();
let var_name = CString::new(var_name).unwrap();
let linkage_name = if no_mangle {
None
} else {
let linkage_name = mangled_name_of_item(cx, node_id);
let linkage_name = mangled_name_of_instance(cx, Instance::mono(tcx, def_id));
Some(CString::new(linkage_name.to_string()).unwrap())
};

View File

@ -254,14 +254,14 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
let linkage_name = mangled_name_of_instance(cx, instance);
let scope_line = span_start(cx, span).line;
let local_id = cx.tcx.hir.as_local_node_id(instance.def_id());
let is_local_to_unit = local_id.map_or(false, |id| is_node_local_to_unit(cx, id));
let is_local_to_unit = is_node_local_to_unit(cx, def_id);
let function_name = CString::new(name).unwrap();
let linkage_name = CString::new(linkage_name.to_string()).unwrap();
let mut flags = DIFlags::FlagPrototyped;
let local_id = cx.tcx.hir.as_local_node_id(def_id);
match *cx.sess().entry_fn.borrow() {
Some((id, _)) => {
if local_id == Some(id) {

View File

@ -14,7 +14,6 @@ use super::metadata::{unknown_file_metadata, UNKNOWN_LINE_NUMBER};
use super::utils::{DIB, debug_context};
use monomorphize::Instance;
use rustc::ty;
use syntax::ast;
use llvm;
use llvm::debuginfo::DIScope;
@ -33,16 +32,6 @@ pub fn mangled_name_of_instance<'a, 'tcx>(
tcx.symbol_name(instance)
}
pub fn mangled_name_of_item<'a, 'tcx>(
cx: &CodegenCx<'a, 'tcx>,
node_id: ast::NodeId,
) -> ty::SymbolName {
let tcx = cx.tcx;
let node_def_id = tcx.hir.local_def_id(node_id);
let instance = Instance::mono(tcx, node_def_id);
tcx.symbol_name(instance)
}
pub fn item_namespace(cx: &CodegenCx, def_id: DefId) -> DIScope {
if let Some(&scope) = debug_context(cx).namespace_map.borrow().get(&def_id) {
return scope;

View File

@ -21,9 +21,8 @@ use llvm::debuginfo::{DIScope, DIBuilderRef, DIDescriptor, DIArray};
use common::{CodegenCx};
use syntax_pos::{self, Span};
use syntax::ast;
pub fn is_node_local_to_unit(cx: &CodegenCx, node_id: ast::NodeId) -> bool
pub fn is_node_local_to_unit(cx: &CodegenCx, def_id: DefId) -> bool
{
// The is_local_to_unit flag indicates whether a function is local to the
// current compilation unit (i.e. if it is *static* in the C-sense). The
@ -33,7 +32,6 @@ pub fn is_node_local_to_unit(cx: &CodegenCx, node_id: ast::NodeId) -> bool
// visible). It might better to use the `exported_items` set from
// `driver::CrateAnalysis` in the future, but (atm) this set is not
// available in the translation pass.
let def_id = cx.tcx.hir.local_def_id(node_id);
!cx.tcx.is_exported_symbol(def_id)
}

View File

@ -24,10 +24,11 @@ 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;
use rustc::ty::layout::LayoutOf;
use syntax::ast;
use syntax::attr;
use std::fmt;
@ -44,19 +45,25 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> {
cx.codegen_unit.name());
match *self.as_mono_item() {
MonoItem::Static(node_id) => {
MonoItem::Static(def_id) => {
let tcx = cx.tcx;
let item = tcx.hir.expect_item(node_id);
if let hir::ItemStatic(_, m, _) = item.node {
match consts::trans_static(&cx, m, item.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")
}
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!("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");
}
};
}
MonoItem::GlobalAsm(node_id) => {
let item = cx.tcx.hir.expect_item(node_id);
@ -91,8 +98,8 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> {
debug!("symbol {}", &symbol_name);
match *self.as_mono_item() {
MonoItem::Static(node_id) => {
predefine_static(cx, node_id, linkage, visibility, &symbol_name);
MonoItem::Static(def_id) => {
predefine_static(cx, def_id, linkage, visibility, &symbol_name);
}
MonoItem::Fn(instance) => {
predefine_fn(cx, instance, linkage, visibility, &symbol_name);
@ -126,17 +133,16 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> {
impl<'a, 'tcx> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {}
fn predefine_static<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
node_id: ast::NodeId,
def_id: DefId,
linkage: Linkage,
visibility: Visibility,
symbol_name: &str) {
let def_id = cx.tcx.hir.local_def_id(node_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))
});