parent
2789b067da
commit
e8cd6cc237
@ -559,6 +559,7 @@ define_dep_nodes!( <'tcx>
|
||||
[] IsReachableNonGeneric(DefId),
|
||||
[] IsMirAvailable(DefId),
|
||||
[] ItemAttrs(DefId),
|
||||
[] TransFnAttrs(DefId),
|
||||
[] FnArgNames(DefId),
|
||||
[] DylibDepFormats(CrateNum),
|
||||
[] IsPanicRuntime(CrateNum),
|
||||
|
@ -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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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 }
|
||||
}
|
||||
|
@ -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!()); }
|
||||
|
@ -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(
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user