]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_trans/trans_item.rs
Rollup merge of #41249 - GuillaumeGomez:rustdoc-render, r=steveklabnik,frewsxcv
[rust.git] / src / librustc_trans / trans_item.rs
index 04a6cb27501b3eab4000d02358d4d2103ca67948..f5556bb8382f6540f58bea55168ad96429475e56 100644 (file)
 //! item-path. This is used for unit testing the code that generates
 //! paths etc in all kinds of annoying scenarios.
 
+use asm;
 use attributes;
 use base;
 use consts;
 use context::{CrateContext, SharedCrateContext};
 use common;
 use declare;
-use glue::DropGlueKind;
 use llvm;
-use monomorphize::{self, Instance};
+use monomorphize::Instance;
 use rustc::dep_graph::DepNode;
 use rustc::hir;
 use rustc::hir::def_id::DefId;
 use syntax::ast::{self, NodeId};
 use syntax::attr;
 use type_of;
-use glue;
-use abi::{Abi, FnType};
 use back::symbol_names;
 use std::fmt::Write;
 use std::iter;
 
 #[derive(PartialEq, Eq, Clone, Copy, Debug, Hash)]
 pub enum TransItem<'tcx> {
-    DropGlue(DropGlueKind<'tcx>),
     Fn(Instance<'tcx>),
-    Static(NodeId)
+    Static(NodeId),
+    GlobalAsm(NodeId),
 }
 
 /// Describes how a translation item will be instantiated in object files.
@@ -93,15 +91,20 @@ pub fn define(&self, ccx: &CrateContext<'a, 'tcx>) {
                     span_bug!(item.span, "Mismatch between hir::Item type and TransItem type")
                 }
             }
+            TransItem::GlobalAsm(node_id) => {
+                let item = ccx.tcx().hir.expect_item(node_id);
+                if let hir::ItemGlobalAsm(ref ga) = item.node {
+                    asm::trans_global_asm(ccx, ga);
+                } else {
+                    span_bug!(item.span, "Mismatch between hir::Item type and TransItem type")
+                }
+            }
             TransItem::Fn(instance) => {
                 let _task = ccx.tcx().dep_graph.in_task(
-                    DepNode::TransCrateItem(instance.def)); // (*)
+                    DepNode::TransCrateItem(instance.def_id())); // (*)
 
                 base::trans_instance(&ccx, instance);
             }
-            TransItem::DropGlue(dg) => {
-                glue::implement_drop_glue(&ccx, dg);
-            }
         }
 
         debug!("END IMPLEMENTING '{} ({})' in cgu {}",
@@ -130,9 +133,7 @@ pub fn predefine(&self,
             TransItem::Fn(instance) => {
                 TransItem::predefine_fn(ccx, instance, linkage, &symbol_name);
             }
-            TransItem::DropGlue(dg) => {
-                TransItem::predefine_drop_glue(ccx, dg, linkage, &symbol_name);
-            }
+            TransItem::GlobalAsm(..) => {}
         }
 
         debug!("END PREDEFINING '{} ({})' in cgu {}",
@@ -146,7 +147,8 @@ fn predefine_static(ccx: &CrateContext<'a, 'tcx>,
                         linkage: llvm::Linkage,
                         symbol_name: &str) {
         let def_id = ccx.tcx().hir.local_def_id(node_id);
-        let ty = ccx.tcx().item_type(def_id);
+        let instance = Instance::mono(ccx.tcx(), def_id);
+        let ty = common::instance_ty(ccx.shared(), &instance);
         let llty = type_of::type_of(ccx, ty);
 
         let g = declare::define_global(ccx, symbol_name, llty).unwrap_or_else(|| {
@@ -156,7 +158,6 @@ fn predefine_static(ccx: &CrateContext<'a, 'tcx>,
 
         unsafe { llvm::LLVMRustSetLinkage(g, linkage) };
 
-        let instance = Instance::mono(ccx.shared(), def_id);
         ccx.instances().borrow_mut().insert(instance, g);
         ccx.statics().borrow_mut().insert(g, def_id);
     }
@@ -168,11 +169,8 @@ fn predefine_fn(ccx: &CrateContext<'a, 'tcx>,
         assert!(!instance.substs.needs_infer() &&
                 !instance.substs.has_param_types());
 
-        let item_ty = ccx.tcx().item_type(instance.def);
-        let item_ty = ccx.tcx().erase_regions(&item_ty);
-        let mono_ty = monomorphize::apply_param_substs(ccx.shared(), instance.substs, &item_ty);
-
-        let attrs = ccx.tcx().get_attrs(instance.def);
+        let mono_ty = common::instance_ty(ccx.shared(), &instance);
+        let attrs = instance.def.attrs(ccx.tcx());
         let lldecl = declare::declare_fn(ccx, symbol_name, mono_ty);
         unsafe { llvm::LLVMRustSetLinkage(lldecl, linkage) };
         base::set_link_section(ccx, lldecl, &attrs);
@@ -181,83 +179,45 @@ fn predefine_fn(ccx: &CrateContext<'a, 'tcx>,
             llvm::SetUniqueComdat(ccx.llmod(), lldecl);
         }
 
-        if let ty::TyClosure(..) = mono_ty.sty {
-            // set an inline hint for all closures
+        debug!("predefine_fn: mono_ty = {:?} instance = {:?}", mono_ty, instance);
+        if common::is_inline_instance(ccx.tcx(), &instance) {
             attributes::inline(lldecl, attributes::InlineAttr::Hint);
         }
-
         attributes::from_fn_attrs(ccx, &attrs, lldecl);
 
         ccx.instances().borrow_mut().insert(instance, lldecl);
     }
 
-    fn predefine_drop_glue(ccx: &CrateContext<'a, 'tcx>,
-                           dg: glue::DropGlueKind<'tcx>,
-                           linkage: llvm::Linkage,
-                           symbol_name: &str) {
-        let tcx = ccx.tcx();
-        assert_eq!(dg.ty(), glue::get_drop_glue_type(ccx.shared(), dg.ty()));
-        let t = dg.ty();
-
-        let sig = tcx.mk_fn_sig(iter::once(tcx.mk_mut_ptr(t)), tcx.mk_nil(), false);
-
-        debug!("predefine_drop_glue: sig={}", sig);
-
-        let fn_ty = FnType::new(ccx, Abi::Rust, &sig, &[]);
-        let llfnty = fn_ty.llvm_type(ccx);
-
-        assert!(declare::get_defined_value(ccx, symbol_name).is_none());
-        let llfn = declare::declare_cfn(ccx, symbol_name, llfnty);
-        unsafe { llvm::LLVMRustSetLinkage(llfn, linkage) };
-        if linkage == llvm::Linkage::LinkOnceODRLinkage ||
-           linkage == llvm::Linkage::WeakODRLinkage {
-            llvm::SetUniqueComdat(ccx.llmod(), llfn);
-        }
-        attributes::set_frame_pointer_elimination(ccx, llfn);
-        ccx.drop_glues().borrow_mut().insert(dg, (llfn, fn_ty));
-    }
-
     pub fn compute_symbol_name(&self,
                                scx: &SharedCrateContext<'a, 'tcx>) -> String {
         match *self {
-            TransItem::Fn(instance) => instance.symbol_name(scx),
+            TransItem::Fn(instance) => symbol_names::symbol_name(instance, scx),
             TransItem::Static(node_id) => {
                 let def_id = scx.tcx().hir.local_def_id(node_id);
-                Instance::mono(scx, def_id).symbol_name(scx)
+                symbol_names::symbol_name(Instance::mono(scx.tcx(), def_id), scx)
             }
-            TransItem::DropGlue(dg) => {
-                let prefix = match dg {
-                    DropGlueKind::Ty(_) => "drop",
-                    DropGlueKind::TyContents(_) => "drop_contents",
-                };
-                symbol_names::exported_name_from_type_and_prefix(scx, dg.ty(), prefix)
+            TransItem::GlobalAsm(node_id) => {
+                let def_id = scx.tcx().hir.local_def_id(node_id);
+                format!("global_asm_{:?}", def_id)
             }
         }
     }
 
-    pub fn is_from_extern_crate(&self) -> bool {
-        match *self {
-            TransItem::Fn(ref instance) => !instance.def.is_local(),
-            TransItem::DropGlue(..) |
-            TransItem::Static(..)   => false,
-        }
-    }
-
     pub fn instantiation_mode(&self,
                               tcx: TyCtxt<'a, 'tcx, 'tcx>)
                               -> InstantiationMode {
         match *self {
             TransItem::Fn(ref instance) => {
                 if self.explicit_linkage(tcx).is_none() &&
-                   (common::is_closure(tcx, instance.def) ||
-                    attr::requests_inline(&tcx.get_attrs(instance.def)[..])) {
+                    common::requests_inline(tcx, instance)
+                {
                     InstantiationMode::LocalCopy
                 } else {
                     InstantiationMode::GloballyShared
                 }
             }
-            TransItem::DropGlue(..) => InstantiationMode::LocalCopy,
             TransItem::Static(..) => InstantiationMode::GloballyShared,
+            TransItem::GlobalAsm(..) => InstantiationMode::GloballyShared,
         }
     }
 
@@ -266,16 +226,16 @@ pub fn is_generic_fn(&self) -> bool {
             TransItem::Fn(ref instance) => {
                 instance.substs.types().next().is_some()
             }
-            TransItem::DropGlue(..) |
-            TransItem::Static(..)   => false,
+            TransItem::Static(..) |
+            TransItem::GlobalAsm(..) => false,
         }
     }
 
     pub fn explicit_linkage(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Option<llvm::Linkage> {
         let def_id = match *self {
-            TransItem::Fn(ref instance) => instance.def,
+            TransItem::Fn(ref instance) => instance.def_id(),
             TransItem::Static(node_id) => tcx.hir.local_def_id(node_id),
-            TransItem::DropGlue(..) => return None,
+            TransItem::GlobalAsm(..) => return None,
         };
 
         let attributes = tcx.get_attrs(def_id);
@@ -299,16 +259,6 @@ pub fn to_string(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> String {
         let hir_map = &tcx.hir;
 
         return match *self {
-            TransItem::DropGlue(dg) => {
-                let mut s = String::with_capacity(32);
-                match dg {
-                    DropGlueKind::Ty(_) => s.push_str("drop-glue "),
-                    DropGlueKind::TyContents(_) => s.push_str("drop-glue-contents "),
-                };
-                let printer = DefPathBasedNames::new(tcx, false, false);
-                printer.push_type_name(dg.ty(), &mut s);
-                s
-            }
             TransItem::Fn(instance) => {
                 to_string_internal(tcx, "fn ", instance)
             },
@@ -317,6 +267,9 @@ pub fn to_string(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> String {
                 let instance = Instance::new(def_id, tcx.intern_substs(&[]));
                 to_string_internal(tcx, "static ", instance)
             },
+            TransItem::GlobalAsm(..) => {
+                "global_asm".to_string()
+            }
         };
 
         fn to_string_internal<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
@@ -333,13 +286,6 @@ fn to_string_internal<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
     pub fn to_raw_string(&self) -> String {
         match *self {
-            TransItem::DropGlue(dg) => {
-                let prefix = match dg {
-                    DropGlueKind::Ty(_) => "Ty",
-                    DropGlueKind::TyContents(_) => "TyContents",
-                };
-                format!("DropGlue({}: {})", prefix, dg.ty() as *const _ as usize)
-            }
             TransItem::Fn(instance) => {
                 format!("Fn({:?}, {})",
                          instance.def,
@@ -348,6 +294,9 @@ pub fn to_raw_string(&self) -> String {
             TransItem::Static(id) => {
                 format!("Static({:?})", id)
             }
+            TransItem::GlobalAsm(id) => {
+                format!("GlobalAsm({:?})", id)
+            }
         }
     }
 }
@@ -457,12 +406,13 @@ pub fn push_type_name(&self, t: Ty<'tcx>, output: &mut String) {
                         output);
                 }
             },
-            ty::TyFnDef(.., &ty::BareFnTy{ unsafety, abi, ref sig } ) |
-            ty::TyFnPtr(&ty::BareFnTy{ unsafety, abi, ref sig } ) => {
-                if unsafety == hir::Unsafety::Unsafe {
+            ty::TyFnDef(.., sig) |
+            ty::TyFnPtr(sig) => {
+                if sig.unsafety() == hir::Unsafety::Unsafe {
                     output.push_str("unsafe ");
                 }
 
+                let abi = sig.abi();
                 if abi != ::abi::Abi::Rust {
                     output.push_str("extern \"");
                     output.push_str(abi.name());
@@ -471,7 +421,7 @@ pub fn push_type_name(&self, t: Ty<'tcx>, output: &mut String) {
 
                 output.push_str("fn(");
 
-                let sig = self.tcx.erase_late_bound_regions_and_normalize(sig);
+                let sig = self.tcx.erase_late_bound_regions_and_normalize(&sig);
 
                 if !sig.inputs().is_empty() {
                     for &parameter_type in sig.inputs() {
@@ -577,7 +527,7 @@ fn push_type_params<I>(&self,
     pub fn push_instance_as_string(&self,
                                    instance: Instance<'tcx>,
                                    output: &mut String) {
-        self.push_def_path(instance.def, output);
+        self.push_def_path(instance.def_id(), output);
         self.push_type_params(instance.substs, iter::empty(), output);
     }
 }