about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/dep_graph/dep_node.rs1
-rw-r--r--src/librustc/hir/mod.rs25
-rw-r--r--src/librustc/ich/impls_hir.rs21
-rw-r--r--src/librustc/ty/maps/mod.rs7
-rw-r--r--src/librustc/ty/maps/plumbing.rs1
-rw-r--r--src/librustc_trans/attributes.rs32
-rw-r--r--src/librustc_typeck/collect.rs26
7 files changed, 98 insertions, 15 deletions
diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs
index 84fdeba4ab3..715dbb16ae4 100644
--- a/src/librustc/dep_graph/dep_node.rs
+++ b/src/librustc/dep_graph/dep_node.rs
@@ -559,6 +559,7 @@ define_dep_nodes!( <'tcx>
     [] IsReachableNonGeneric(DefId),
     [] IsMirAvailable(DefId),
     [] ItemAttrs(DefId),
+    [] TransFnAttrs(DefId),
     [] FnArgNames(DefId),
     [] DylibDepFormats(CrateNum),
     [] IsPanicRuntime(CrateNum),
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index c4873cb8307..5de341ef511 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -2210,3 +2210,28 @@ pub type GlobMap = NodeMap<FxHashSet<Name>>;
 pub fn provide(providers: &mut Providers) {
     providers.describe_def = map::describe_def;
 }
+
+#[derive(Clone, RustcEncodable, RustcDecodable, Hash)]
+pub struct TransFnAttrs {
+    pub flags: TransFnAttrFlags,
+}
+
+bitflags! {
+    #[derive(RustcEncodable, RustcDecodable)]
+    pub struct TransFnAttrFlags: u8 {
+        const COLD                      = 0b0000_0001;
+        const ALLOCATOR                 = 0b0000_0010;
+        const UNWIND                    = 0b0000_0100;
+        const RUSTC_ALLOCATOR_NOUNWIND  = 0b0000_1000;
+        const NAKED                     = 0b0001_0000;
+    }
+}
+
+impl TransFnAttrs {
+    pub fn new() -> TransFnAttrs {
+        TransFnAttrs {
+            flags: TransFnAttrFlags::empty(),
+        }
+    }
+}
+
diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs
index 7dca96f94e6..d3151476fff 100644
--- a/src/librustc/ich/impls_hir.rs
+++ b/src/librustc/ich/impls_hir.rs
@@ -1138,6 +1138,27 @@ impl<'gcx> ToStableHashKey<StableHashingContext<'gcx>> for hir::TraitCandidate {
     }
 }
 
+impl<'hir> HashStable<StableHashingContext<'hir>> for hir::TransFnAttrs
+{
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'hir>,
+                                          hasher: &mut StableHasher<W>) {
+        let hir::TransFnAttrs {
+            flags,
+        } = *self;
+
+        flags.hash_stable(hcx, hasher);
+    }
+}
+
+impl<'hir> HashStable<StableHashingContext<'hir>> for hir::TransFnAttrFlags
+{
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'hir>,
+                                          hasher: &mut StableHasher<W>) {
+        self.bits().hash_stable(hcx, hasher);
+    }
+}
 
 impl_stable_hash_for!(struct hir::Freevar {
     def,
diff --git a/src/librustc/ty/maps/mod.rs b/src/librustc/ty/maps/mod.rs
index 2ef97b2673d..fd3aee77e36 100644
--- a/src/librustc/ty/maps/mod.rs
+++ b/src/librustc/ty/maps/mod.rs
@@ -12,7 +12,7 @@ use dep_graph::{DepConstructor, DepNode};
 use errors::DiagnosticBuilder;
 use hir::def_id::{CrateNum, DefId, DefIndex};
 use hir::def::{Def, Export};
-use hir::{self, TraitCandidate, ItemLocalId};
+use hir::{self, TraitCandidate, ItemLocalId, TransFnAttrs};
 use hir::svh::Svh;
 use lint;
 use middle::borrowck::BorrowCheckResult;
@@ -235,6 +235,7 @@ define_maps! { <'tcx>
     [] fn lookup_stability: LookupStability(DefId) -> Option<&'tcx attr::Stability>,
     [] fn lookup_deprecation_entry: LookupDeprecationEntry(DefId) -> Option<DeprecationEntry>,
     [] fn item_attrs: ItemAttrs(DefId) -> Lrc<[ast::Attribute]>,
+    [] fn trans_fn_attrs: trans_fn_attrs(DefId) -> TransFnAttrs,
     [] fn fn_arg_names: FnArgNames(DefId) -> Vec<ast::Name>,
     [] fn impl_parent: ImplParent(DefId) -> Option<DefId>,
     [] fn trait_of_item: TraitOfItem(DefId) -> Option<DefId>,
@@ -403,6 +404,10 @@ fn features_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
     DepConstructor::Features
 }
 
+fn trans_fn_attrs<'tcx>(id: DefId) -> DepConstructor<'tcx> {
+    DepConstructor::TransFnAttrs { 0: id }
+}
+
 fn erase_regions_ty<'tcx>(ty: Ty<'tcx>) -> DepConstructor<'tcx> {
     DepConstructor::EraseRegionsTy { ty }
 }
diff --git a/src/librustc/ty/maps/plumbing.rs b/src/librustc/ty/maps/plumbing.rs
index 13f286d6a26..9082037e10c 100644
--- a/src/librustc/ty/maps/plumbing.rs
+++ b/src/librustc/ty/maps/plumbing.rs
@@ -854,6 +854,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
         DepKind::IsReachableNonGeneric => { force!(is_reachable_non_generic, def_id!()); }
         DepKind::IsMirAvailable => { force!(is_mir_available, def_id!()); }
         DepKind::ItemAttrs => { force!(item_attrs, def_id!()); }
+        DepKind::TransFnAttrs => { force!(trans_fn_attrs, def_id!()); }
         DepKind::FnArgNames => { force!(fn_arg_names, def_id!()); }
         DepKind::DylibDepFormats => { force!(dylib_dependency_formats, krate!()); }
         DepKind::IsPanicRuntime => { force!(is_panic_runtime, krate!()); }
diff --git a/src/librustc_trans/attributes.rs b/src/librustc_trans/attributes.rs
index ffa3f7f4011..92447d516c3 100644
--- a/src/librustc_trans/attributes.rs
+++ b/src/librustc_trans/attributes.rs
@@ -11,6 +11,7 @@
 
 use std::ffi::{CStr, CString};
 
+use rustc::hir::TransFnAttrFlags;
 use rustc::hir::Unsafety;
 use rustc::hir::def_id::{DefId, LOCAL_CRATE};
 use rustc::session::config::Sanitizer;
@@ -109,22 +110,27 @@ pub fn from_fn_attrs(cx: &CodegenCx, llfn: ValueRef, id: DefId) {
     set_frame_pointer_elimination(cx, llfn);
     set_probestack(cx, llfn);
 
-    for attr in attrs.iter() {
-        if attr.check_name("cold") {
-            Attribute::Cold.apply_llfn(Function, llfn);
-        } else if attr.check_name("naked") {
-            naked(llfn, true);
-        } else if attr.check_name("allocator") {
-            Attribute::NoAlias.apply_llfn(
-                llvm::AttributePlace::ReturnValue, llfn);
-        } else if attr.check_name("unwind") {
-            unwind(llfn, true);
-        } else if attr.check_name("rustc_allocator_nounwind") {
-            unwind(llfn, false);
-        }
+    let trans_fn_attrs = cx.tcx.trans_fn_attrs(id);
+
+    if trans_fn_attrs.flags.contains(TransFnAttrFlags::COLD) {
+        Attribute::Cold.apply_llfn(Function, llfn);
+    }
+    if trans_fn_attrs.flags.contains(TransFnAttrFlags::NAKED) {
+        naked(llfn, true);
+    }
+    if trans_fn_attrs.flags.contains(TransFnAttrFlags::ALLOCATOR) {
+        Attribute::NoAlias.apply_llfn(
+            llvm::AttributePlace::ReturnValue, llfn);
+    }
+    if trans_fn_attrs.flags.contains(TransFnAttrFlags::UNWIND) {
+        unwind(llfn, true);
+    }
+    if trans_fn_attrs.flags.contains(TransFnAttrFlags::RUSTC_ALLOCATOR_NOUNWIND) {
+        unwind(llfn, false);
     }
 
     let target_features = cx.tcx.target_features_enabled(id);
+
     if !target_features.is_empty() {
         let val = CString::new(target_features.join(",")).unwrap();
         llvm::AddFunctionAttrStringValue(
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index f7158593f0b..f85af64bb4b 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -45,7 +45,7 @@ use syntax::codemap::Spanned;
 use syntax::symbol::{Symbol, keywords};
 use syntax_pos::{Span, DUMMY_SP};
 
-use rustc::hir::{self, map as hir_map};
+use rustc::hir::{self, map as hir_map, TransFnAttrs, TransFnAttrFlags};
 use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
 use rustc::hir::def::{Def, CtorKind};
 use rustc::hir::def_id::DefId;
@@ -71,6 +71,7 @@ pub fn provide(providers: &mut Providers) {
         impl_trait_ref,
         impl_polarity,
         is_foreign_item,
+        trans_fn_attrs,
         ..*providers
     };
 }
@@ -1723,3 +1724,26 @@ fn is_foreign_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         _ => bug!("is_foreign_item applied to non-local def-id {:?}", def_id)
     }
 }
+
+fn trans_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> TransFnAttrs {
+    let attrs = tcx.get_attrs(id);
+
+    let mut trans_fn_attrs = TransFnAttrs::new();
+
+    for attr in attrs.iter() {
+        if attr.check_name("cold") {
+            trans_fn_attrs.flags |= TransFnAttrFlags::COLD;
+        } else if attr.check_name("allocator") {
+            trans_fn_attrs.flags |= TransFnAttrFlags::ALLOCATOR;
+        } else if attr.check_name("unwind") {
+            trans_fn_attrs.flags |= TransFnAttrFlags::UNWIND;
+        } else if attr.check_name("rustc_allocator_nounwind") {
+            trans_fn_attrs.flags |= TransFnAttrFlags::RUSTC_ALLOCATOR_NOUNWIND;
+        } else if attr.check_name("naked") {
+            trans_fn_attrs.flags |= TransFnAttrFlags::NAKED;
+        } else if attr.check_name("inline") {
+        }
+    }
+
+    trans_fn_attrs
+}