mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-11 16:15:03 +00:00
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:
commit
2483d842fb
@ -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,
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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); }
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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)),
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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())
|
||||
};
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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))
|
||||
});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user