summaryrefslogtreecommitdiff
path: root/src/librustc_llvm/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/librustc_llvm/lib.rs')
-rw-r--r--src/librustc_llvm/lib.rs162
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