diff options
Diffstat (limited to 'src/librustc_llvm/lib.rs')
-rw-r--r-- | src/librustc_llvm/lib.rs | 162 |
1 files changed, 59 insertions, 103 deletions
diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs index bc54b1ebab7..a1dca796d9a 100644 --- a/src/librustc_llvm/lib.rs +++ b/src/librustc_llvm/lib.rs @@ -33,8 +33,6 @@ extern crate libc; #[macro_use] #[no_link] extern crate rustc_bitflags; -pub use self::OtherAttribute::*; -pub use self::SpecialAttribute::*; pub use self::AttributeSet::*; pub use self::IntPredicate::*; pub use self::RealPredicate::*; @@ -133,6 +131,7 @@ pub enum DLLStorageClassTypes { } bitflags! { + #[derive(Default, Debug)] flags Attribute : u64 { const ZExt = 1 << 0, const SExt = 1 << 1, @@ -150,138 +149,95 @@ bitflags! { const OptimizeForSize = 1 << 13, const StackProtect = 1 << 14, const StackProtectReq = 1 << 15, - const Alignment = 1 << 16, const NoCapture = 1 << 21, const NoRedZone = 1 << 22, const NoImplicitFloat = 1 << 23, const Naked = 1 << 24, const InlineHint = 1 << 25, - const Stack = 7 << 26, const ReturnsTwice = 1 << 29, const UWTable = 1 << 30, const NonLazyBind = 1 << 31, + + // Some of these are missing from the LLVM C API, the rest are + // present, but commented out, and preceded by the following warning: + // FIXME: These attributes are currently not included in the C API as + // a temporary measure until the API/ABI impact to the C API is understood + // and the path forward agreed upon. + const SanitizeAddress = 1 << 32, + const MinSize = 1 << 33, + const NoDuplicate = 1 << 34, + const StackProtectStrong = 1 << 35, + const SanitizeThread = 1 << 36, + const SanitizeMemory = 1 << 37, + const NoBuiltin = 1 << 38, + const Returned = 1 << 39, + const Cold = 1 << 40, + const Builtin = 1 << 41, const OptimizeNone = 1 << 42, + const InAlloca = 1 << 43, + const NonNull = 1 << 44, + const JumpTable = 1 << 45, + const Convergent = 1 << 46, + const SafeStack = 1 << 47, + const NoRecurse = 1 << 48, + const InaccessibleMemOnly = 1 << 49, + const InaccessibleMemOrArgMemOnly = 1 << 50, } } - -#[repr(u64)] -#[derive(Copy, Clone)] -pub enum OtherAttribute { - // The following are not really exposed in - // the LLVM C api so instead to add these - // we call a wrapper function in RustWrapper - // that uses the C++ api. - SanitizeAddressAttribute = 1 << 32, - MinSizeAttribute = 1 << 33, - NoDuplicateAttribute = 1 << 34, - StackProtectStrongAttribute = 1 << 35, - SanitizeThreadAttribute = 1 << 36, - SanitizeMemoryAttribute = 1 << 37, - NoBuiltinAttribute = 1 << 38, - ReturnedAttribute = 1 << 39, - ColdAttribute = 1 << 40, - BuiltinAttribute = 1 << 41, - OptimizeNoneAttribute = 1 << 42, - InAllocaAttribute = 1 << 43, - NonNullAttribute = 1 << 44, -} - -#[derive(Copy, Clone)] -pub enum SpecialAttribute { - DereferenceableAttribute(u64) -} - -#[repr(C)] -#[derive(Copy, Clone)] -pub enum AttributeSet { - ReturnIndex = 0, - FunctionIndex = !0 -} - -pub trait AttrHelper { - fn apply_llfn(&self, idx: c_uint, llfn: ValueRef); - fn apply_callsite(&self, idx: c_uint, callsite: ValueRef); +#[derive(Copy, Clone, Default, Debug)] +pub struct Attributes { + regular: Attribute, + dereferenceable_bytes: u64 } -impl AttrHelper for Attribute { - fn apply_llfn(&self, idx: c_uint, llfn: ValueRef) { - unsafe { - LLVMAddFunctionAttribute(llfn, idx, self.bits() as uint64_t); - } +impl Attributes { + pub fn set(&mut self, attr: Attribute) -> &mut Self { + self.regular = self.regular | attr; + self } - fn apply_callsite(&self, idx: c_uint, callsite: ValueRef) { - unsafe { - LLVMAddCallSiteAttribute(callsite, idx, self.bits() as uint64_t); - } + pub fn unset(&mut self, attr: Attribute) -> &mut Self { + self.regular = self.regular - attr; + self } -} -impl AttrHelper for OtherAttribute { - fn apply_llfn(&self, idx: c_uint, llfn: ValueRef) { - unsafe { - LLVMAddFunctionAttribute(llfn, idx, *self as uint64_t); - } + pub fn set_dereferenceable(&mut self, bytes: u64) -> &mut Self { + self.dereferenceable_bytes = bytes; + self } - fn apply_callsite(&self, idx: c_uint, callsite: ValueRef) { - unsafe { - LLVMAddCallSiteAttribute(callsite, idx, *self as uint64_t); - } + pub fn unset_dereferenceable(&mut self) -> &mut Self { + self.dereferenceable_bytes = 0; + self } -} -impl AttrHelper for SpecialAttribute { - fn apply_llfn(&self, idx: c_uint, llfn: ValueRef) { - match *self { - DereferenceableAttribute(bytes) => unsafe { - LLVMAddDereferenceableAttr(llfn, idx, bytes as uint64_t); + pub fn apply_llfn(&self, idx: usize, llfn: ValueRef) { + unsafe { + LLVMAddFunctionAttribute(llfn, idx as c_uint, self.regular.bits()); + if self.dereferenceable_bytes != 0 { + LLVMAddDereferenceableAttr(llfn, idx as c_uint, + self.dereferenceable_bytes); } } } - fn apply_callsite(&self, idx: c_uint, callsite: ValueRef) { - match *self { - DereferenceableAttribute(bytes) => unsafe { - LLVMAddDereferenceableCallSiteAttr(callsite, idx, bytes as uint64_t); + pub fn apply_callsite(&self, idx: usize, callsite: ValueRef) { + unsafe { + LLVMAddCallSiteAttribute(callsite, idx as c_uint, self.regular.bits()); + if self.dereferenceable_bytes != 0 { + LLVMAddDereferenceableCallSiteAttr(callsite, idx as c_uint, + self.dereferenceable_bytes); } } } } -pub struct AttrBuilder { - attrs: Vec<(usize, Box<AttrHelper+'static>)> -} - -impl AttrBuilder { - pub fn new() -> AttrBuilder { - AttrBuilder { - attrs: Vec::new() - } - } - - pub fn arg<T: AttrHelper + 'static>(&mut self, idx: usize, a: T) -> &mut AttrBuilder { - self.attrs.push((idx, box a as Box<AttrHelper+'static>)); - self - } - - pub fn ret<T: AttrHelper + 'static>(&mut self, a: T) -> &mut AttrBuilder { - self.attrs.push((ReturnIndex as usize, box a as Box<AttrHelper+'static>)); - self - } - - pub fn apply_llfn(&self, llfn: ValueRef) { - for &(idx, ref attr) in &self.attrs { - attr.apply_llfn(idx as c_uint, llfn); - } - } - - pub fn apply_callsite(&self, callsite: ValueRef) { - for &(idx, ref attr) in &self.attrs { - attr.apply_callsite(idx as c_uint, callsite); - } - } +#[repr(C)] +#[derive(Copy, Clone)] +pub enum AttributeSet { + ReturnIndex = 0, + FunctionIndex = !0 } // enum for the LLVM IntPredicate type |