diff --git a/src/librustc_llvm/ffi.rs b/src/librustc_llvm/ffi.rs index 53a287ea8ec0d..6301c57c55540 100644 --- a/src/librustc_llvm/ffi.rs +++ b/src/librustc_llvm/ffi.rs @@ -13,19 +13,20 @@ use debuginfo::{DIBuilderRef, DIDescriptor, DIBasicType, DIDerivedType, DICompositeType, DIScope, DIVariable, DIGlobalVariable, DIArray, DISubrange, DITemplateTypeParameter, DIEnumerator, DINameSpace}; -use RustStringRef; -use libc::{c_uint, c_ushort, c_int, size_t, c_char}; +use libc::{c_uint, c_int, size_t, c_char}; use libc::{c_longlong, c_ulonglong, c_void}; +use RustStringRef; + pub type Opcode = u32; pub type Bool = c_uint; pub const True: Bool = 1 as Bool; pub const False: Bool = 0 as Bool; -#[repr(C)] #[derive(Copy, Clone, PartialEq)] +#[repr(C)] pub enum LLVMRustResult { Success, Failure, @@ -68,8 +69,8 @@ pub enum Linkage { } /// LLVMDiagnosticSeverity -#[repr(C)] #[derive(Copy, Clone, Debug)] +#[repr(C)] pub enum DiagnosticSeverity { Error = 0, Warning = 1, @@ -77,14 +78,13 @@ pub enum DiagnosticSeverity { Note = 3, } -/// LLVMRustDLLStorageClassTypes -#[repr(C)] +/// LLVMDLLStorageClass #[derive(Copy, Clone)] -pub enum DLLStorageClassTypes { - Other, - Default, - DllImport, - DllExport, +#[repr(C)] +pub enum DLLStorageClass { + Default = 0, + DllImport = 1, /* Function to be imported from DLL. */ + DllExport = 2, /* Function to be accessible from DLL. */ } bitflags! { @@ -144,6 +144,7 @@ bitflags! { /// LLVMIntPredicate #[derive(Copy, Clone)] +#[repr(C)] pub enum IntPredicate { IntEQ = 32, IntNE = 33, @@ -159,6 +160,7 @@ pub enum IntPredicate { /// LLVMRealPredicate #[derive(Copy, Clone)] +#[repr(C)] pub enum RealPredicate { RealPredicateFalse = 0, RealOEQ = 1, @@ -178,7 +180,7 @@ pub enum RealPredicate { RealPredicateTrue = 15, } -/// LLVMTypeKind; FIXME: wrap +/// LLVMTypeKind #[derive(Copy, Clone, PartialEq, Debug)] #[repr(C)] pub enum TypeKind { @@ -198,11 +200,12 @@ pub enum TypeKind { Vector = 13, Metadata = 14, X86_MMX = 15, + Token = 16, } /// LLVMAtomicRmwBinOp -#[repr(C)] #[derive(Copy, Clone)] +#[repr(C)] pub enum AtomicRmwBinOp { AtomicXchg = 0, AtomicAdd = 1, @@ -218,8 +221,8 @@ pub enum AtomicRmwBinOp { } /// LLVMAtomicOrdering -#[repr(C)] #[derive(Copy, Clone)] +#[repr(C)] pub enum AtomicOrdering { NotAtomic = 0, Unordered = 1, @@ -232,8 +235,8 @@ pub enum AtomicOrdering { } /// LLVMRustSynchronizationScope -#[repr(C)] #[derive(Copy, Clone)] +#[repr(C)] pub enum SynchronizationScope { Other, SingleThread, @@ -241,16 +244,18 @@ pub enum SynchronizationScope { } /// LLVMRustFileType -#[repr(C)] #[derive(Copy, Clone)] +#[repr(C)] pub enum FileType { Other, AssemblyFile, ObjectFile, } -/// FIXME: ? +/// Enum pinned in LLVMContext, used in +/// LLVMSetMetadata so ABI-stable. #[derive(Copy, Clone)] +#[repr(C)] pub enum MetadataType { MD_dbg = 0, MD_tbaa = 1, @@ -266,11 +271,13 @@ pub enum MetadataType { MD_nonnull = 11, } -/// FIXME: ? +/// LLVMRustAsmDialect #[derive(Copy, Clone)] +#[repr(C)] pub enum AsmDialect { - AD_ATT = 0, - AD_Intel = 1 + Other, + Att, + Intel, } /// LLVMRustCodeGenOptLevel @@ -295,8 +302,8 @@ pub enum RelocMode { } /// LLVMRustCodeModel -#[repr(C)] #[derive(Copy, Clone)] +#[repr(C)] pub enum CodeModel { Other, Default, @@ -308,8 +315,8 @@ pub enum CodeModel { } /// LLVMRustDiagnosticKind -#[repr(C)] #[derive(Copy, Clone)] +#[repr(C)] pub enum DiagnosticKind { Other, InlineAsm, @@ -326,8 +333,8 @@ pub enum DiagnosticKind { } /// LLVMRustArchiveKind -#[repr(C)] #[derive(Copy, Clone)] +#[repr(C)] pub enum ArchiveKind { Other, K_GNU, @@ -335,6 +342,7 @@ pub enum ArchiveKind { K_BSD, K_COFF, } + /// LLVMRustPassKind #[derive(Copy, Clone, PartialEq, Debug)] #[repr(C)] @@ -519,7 +527,7 @@ extern { pub fn LLVMSetModuleInlineAsm(M: ModuleRef, Asm: *const c_char); /// See llvm::LLVMTypeKind::getTypeID. - pub fn LLVMGetTypeKind(Ty: TypeRef) -> TypeKind; + pub fn LLVMRustGetTypeKind(Ty: TypeRef) -> TypeKind; /// See llvm::LLVMType::getContext. pub fn LLVMGetTypeContext(Ty: TypeRef) -> ContextRef; @@ -589,8 +597,6 @@ extern { pub fn LLVMSetValueName(Val: ValueRef, Name: *const c_char); pub fn LLVMDumpValue(Val: ValueRef); pub fn LLVMReplaceAllUsesWith(OldVal: ValueRef, NewVal: ValueRef); - pub fn LLVMHasMetadata(Val: ValueRef) -> c_int; - pub fn LLVMGetMetadata(Val: ValueRef, KindID: c_uint) -> ValueRef; pub fn LLVMSetMetadata(Val: ValueRef, KindID: c_uint, Node: ValueRef); /* Operations on Uses */ @@ -608,9 +614,9 @@ extern { pub fn LLVMConstNull(Ty: TypeRef) -> ValueRef; /* all zeroes */ pub fn LLVMConstAllOnes(Ty: TypeRef) -> ValueRef; - pub fn LLVMConstICmp(Pred: c_ushort, V1: ValueRef, V2: ValueRef) + pub fn LLVMConstICmp(Pred: IntPredicate, V1: ValueRef, V2: ValueRef) -> ValueRef; - pub fn LLVMConstFCmp(Pred: c_ushort, V1: ValueRef, V2: ValueRef) + pub fn LLVMConstFCmp(Pred: RealPredicate, V1: ValueRef, V2: ValueRef) -> ValueRef; /* only for isize/vector */ pub fn LLVMGetUndef(Ty: TypeRef) -> ValueRef; @@ -815,13 +821,15 @@ extern { pub fn LLVMGetGlobalParent(Global: ValueRef) -> ModuleRef; pub fn LLVMIsDeclaration(Global: ValueRef) -> Bool; pub fn LLVMGetLinkage(Global: ValueRef) -> c_uint; - pub fn LLVMSetLinkage(Global: ValueRef, Link: c_uint); + pub fn LLVMSetLinkage(Global: ValueRef, Link: Linkage); pub fn LLVMGetSection(Global: ValueRef) -> *const c_char; pub fn LLVMSetSection(Global: ValueRef, Section: *const c_char); pub fn LLVMGetVisibility(Global: ValueRef) -> c_uint; pub fn LLVMSetVisibility(Global: ValueRef, Viz: c_uint); pub fn LLVMGetAlignment(Global: ValueRef) -> c_uint; pub fn LLVMSetAlignment(Global: ValueRef, Bytes: c_uint); + pub fn LLVMSetDLLStorageClass(V: ValueRef, + C: DLLStorageClass); /* Operations on global variables */ @@ -1685,7 +1693,7 @@ extern { Constraints: *const c_char, SideEffects: Bool, AlignStack: Bool, - Dialect: c_uint) + Dialect: AsmDialect) -> ValueRef; pub fn LLVMRustDebugMetadataVersion() -> u32; @@ -1990,9 +1998,6 @@ extern { pub fn LLVMRustArchiveIteratorFree(AIR: ArchiveIteratorRef); pub fn LLVMRustDestroyArchive(AR: ArchiveRef); - pub fn LLVMRustSetDLLStorageClass(V: ValueRef, - C: DLLStorageClassTypes); - pub fn LLVMRustGetSectionName(SI: SectionIteratorRef, data: *mut *const c_char) -> size_t; diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs index f451b167196c9..6c4e1a54ea728 100644 --- a/src/librustc_llvm/lib.rs +++ b/src/librustc_llvm/lib.rs @@ -33,13 +33,11 @@ extern crate libc; #[macro_use] #[no_link] extern crate rustc_bitflags; -pub use self::AttributeSet::*; pub use self::IntPredicate::*; pub use self::RealPredicate::*; pub use self::TypeKind::*; pub use self::AtomicRmwBinOp::*; pub use self::MetadataType::*; -pub use self::AsmDialect::*; pub use self::CodeGenOptSize::*; pub use self::DiagnosticKind::*; pub use self::CallConv::*; @@ -50,7 +48,7 @@ use std::str::FromStr; use std::slice; use std::ffi::{CString, CStr}; use std::cell::RefCell; -use libc::{c_uint, c_ushort, c_char, size_t}; +use libc::{c_uint, c_char, size_t}; pub mod archive_ro; pub mod diagnostic; @@ -94,32 +92,64 @@ impl Attributes { self } - pub fn apply_llfn(&self, idx: usize, llfn: ValueRef) { + pub fn apply_llfn(&self, idx: AttributePlace, llfn: ValueRef) { unsafe { - LLVMRustAddFunctionAttribute(llfn, idx as c_uint, self.regular.bits()); + self.regular.apply_llfn(idx, llfn); if self.dereferenceable_bytes != 0 { - LLVMRustAddDereferenceableAttr(llfn, idx as c_uint, - self.dereferenceable_bytes); + LLVMRustAddDereferenceableAttr( + llfn, + idx.as_uint(), + self.dereferenceable_bytes); } } } - pub fn apply_callsite(&self, idx: usize, callsite: ValueRef) { + pub fn apply_callsite(&self, idx: AttributePlace, callsite: ValueRef) { unsafe { - LLVMRustAddCallSiteAttribute(callsite, idx as c_uint, self.regular.bits()); + self.regular.apply_callsite(idx, callsite); if self.dereferenceable_bytes != 0 { - LLVMRustAddDereferenceableCallSiteAttr(callsite, idx as c_uint, - self.dereferenceable_bytes); + LLVMRustAddDereferenceableCallSiteAttr( + callsite, + idx.as_uint(), + self.dereferenceable_bytes); } } } } +pub fn AddFunctionAttrStringValue( + llfn: ValueRef, + idx: AttributePlace, + attr: &'static str, + value: &'static str +) { + unsafe { + LLVMRustAddFunctionAttrStringValue( + llfn, + idx.as_uint(), + attr.as_ptr() as *const _, + value.as_ptr() as *const _) + } +} + #[repr(C)] #[derive(Copy, Clone)] -pub enum AttributeSet { - ReturnIndex = 0, - FunctionIndex = !0 +pub enum AttributePlace { + Argument(u32), + Function, +} + +impl AttributePlace { + pub fn ReturnValue() -> Self { + AttributePlace::Argument(0) + } + + fn as_uint(self) -> c_uint { + match self { + AttributePlace::Function => !0, + AttributePlace::Argument(i) => i, + } + } } #[derive(Copy, Clone, PartialEq)] @@ -170,11 +200,6 @@ pub fn SetFunctionCallConv(fn_: ValueRef, cc: CallConv) { LLVMSetFunctionCallConv(fn_, cc as c_uint); } } -pub fn SetLinkage(global: ValueRef, link: Linkage) { - unsafe { - LLVMSetLinkage(global, link as c_uint); - } -} // Externally visible symbols that might appear in multiple translation units need to appear in // their own comdat section so that the duplicates can be discarded at link time. This can for @@ -194,12 +219,6 @@ pub fn UnsetComdat(val: ValueRef) { } } -pub fn SetDLLStorageClass(global: ValueRef, class: DLLStorageClassTypes) { - unsafe { - LLVMRustSetDLLStorageClass(global, class); - } -} - pub fn SetUnnamedAddr(global: ValueRef, unnamed: bool) { unsafe { LLVMSetUnnamedAddr(global, unnamed as Bool); @@ -212,29 +231,40 @@ pub fn set_thread_local(global: ValueRef, is_thread_local: bool) { } } -pub fn ConstICmp(pred: IntPredicate, v1: ValueRef, v2: ValueRef) -> ValueRef { - unsafe { - LLVMConstICmp(pred as c_ushort, v1, v2) +impl Attribute { + pub fn apply_llfn(&self, idx: AttributePlace, llfn: ValueRef) { + unsafe { + LLVMRustAddFunctionAttribute( + llfn, idx.as_uint(), self.bits()) + } } -} -pub fn ConstFCmp(pred: RealPredicate, v1: ValueRef, v2: ValueRef) -> ValueRef { - unsafe { - LLVMConstFCmp(pred as c_ushort, v1, v2) + + pub fn apply_callsite(&self, idx: AttributePlace, callsite: ValueRef) { + unsafe { + LLVMRustAddCallSiteAttribute( + callsite, idx.as_uint(), self.bits()) + } } -} -pub fn SetFunctionAttribute(fn_: ValueRef, attr: Attribute) { - unsafe { - LLVMRustAddFunctionAttribute(fn_, FunctionIndex as c_uint, - attr.bits() as u64) + pub fn unapply_llfn(&self, idx: AttributePlace, llfn: ValueRef) { + unsafe { + LLVMRustRemoveFunctionAttributes( + llfn, idx.as_uint(), self.bits()) + } } -} -pub fn RemoveFunctionAttributes(fn_: ValueRef, attr: Attribute) { - unsafe { - LLVMRustRemoveFunctionAttributes(fn_, FunctionIndex as c_uint, - attr.bits() as u64) + pub fn toggle_llfn(&self, + idx: AttributePlace, + llfn: ValueRef, + set: bool) + { + if set { + self.apply_llfn(idx, llfn); + } else { + self.unapply_llfn(idx, llfn); + } } + } /* Memory-managed interface to target data. */ diff --git a/src/librustc_trans/abi.rs b/src/librustc_trans/abi.rs index 6c2a09f8060c5..587c03af3abb6 100644 --- a/src/librustc_trans/abi.rs +++ b/src/librustc_trans/abi.rs @@ -552,13 +552,13 @@ impl FnType { pub fn apply_attrs_llfn(&self, llfn: ValueRef) { let mut i = if self.ret.is_indirect() { 1 } else { 0 }; if !self.ret.is_ignore() { - self.ret.attrs.apply_llfn(i, llfn); + self.ret.attrs.apply_llfn(llvm::AttributePlace::Argument(i), llfn); } i += 1; for arg in &self.args { if !arg.is_ignore() { if arg.pad.is_some() { i += 1; } - arg.attrs.apply_llfn(i, llfn); + arg.attrs.apply_llfn(llvm::AttributePlace::Argument(i), llfn); i += 1; } } @@ -567,13 +567,13 @@ impl FnType { pub fn apply_attrs_callsite(&self, callsite: ValueRef) { let mut i = if self.ret.is_indirect() { 1 } else { 0 }; if !self.ret.is_ignore() { - self.ret.attrs.apply_callsite(i, callsite); + self.ret.attrs.apply_callsite(llvm::AttributePlace::Argument(i), callsite); } i += 1; for arg in &self.args { if !arg.is_ignore() { if arg.pad.is_some() { i += 1; } - arg.attrs.apply_callsite(i, callsite); + arg.attrs.apply_callsite(llvm::AttributePlace::Argument(i), callsite); i += 1; } } diff --git a/src/librustc_trans/asm.rs b/src/librustc_trans/asm.rs index e27bec683757a..5514fb0f4efc3 100644 --- a/src/librustc_trans/asm.rs +++ b/src/librustc_trans/asm.rs @@ -83,8 +83,8 @@ pub fn trans_inline_asm<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, }; let dialect = match ia.dialect { - AsmDialect::Att => llvm::AD_ATT, - AsmDialect::Intel => llvm::AD_Intel + AsmDialect::Att => llvm::AsmDialect::Att, + AsmDialect::Intel => llvm::AsmDialect::Intel, }; let asm = CString::new(ia.asm.as_bytes()).unwrap(); diff --git a/src/librustc_trans/attributes.rs b/src/librustc_trans/attributes.rs index 9c121ae9bfc6a..62eac35e0abd9 100644 --- a/src/librustc_trans/attributes.rs +++ b/src/librustc_trans/attributes.rs @@ -9,8 +9,8 @@ // except according to those terms. //! Set and unset common attributes on LLVM values. -use libc::c_uint; -use llvm::{self, ValueRef}; +use llvm::{self, Attribute, ValueRef}; +use llvm::AttributePlace::Function; pub use syntax::attr::InlineAttr; use syntax::ast; use context::CrateContext; @@ -20,14 +20,14 @@ use context::CrateContext; pub fn inline(val: ValueRef, inline: InlineAttr) { use self::InlineAttr::*; match inline { - Hint => llvm::SetFunctionAttribute(val, llvm::Attribute::InlineHint), - Always => llvm::SetFunctionAttribute(val, llvm::Attribute::AlwaysInline), - Never => llvm::SetFunctionAttribute(val, llvm::Attribute::NoInline), + Hint => Attribute::InlineHint.apply_llfn(Function, val), + Always => Attribute::AlwaysInline.apply_llfn(Function, val), + Never => Attribute::NoInline.apply_llfn(Function, val), None => { - let attr = llvm::Attribute::InlineHint | - llvm::Attribute::AlwaysInline | - llvm::Attribute::NoInline; - llvm::RemoveFunctionAttributes(val, attr) + let attr = Attribute::InlineHint | + Attribute::AlwaysInline | + Attribute::NoInline; + attr.unapply_llfn(Function, val) }, }; } @@ -35,56 +35,37 @@ pub fn inline(val: ValueRef, inline: InlineAttr) { /// Tell LLVM to emit or not emit the information necessary to unwind the stack for the function. #[inline] pub fn emit_uwtable(val: ValueRef, emit: bool) { - if emit { - llvm::SetFunctionAttribute(val, llvm::Attribute::UWTable); - } else { - llvm::RemoveFunctionAttributes(val, llvm::Attribute::UWTable); - } + Attribute::UWTable.toggle_llfn(Function, val, emit); } /// Tell LLVM whether the function can or cannot unwind. #[inline] pub fn unwind(val: ValueRef, can_unwind: bool) { - if can_unwind { - llvm::RemoveFunctionAttributes(val, llvm::Attribute::NoUnwind); - } else { - llvm::SetFunctionAttribute(val, llvm::Attribute::NoUnwind); - } + Attribute::NoUnwind.toggle_llfn(Function, val, !can_unwind); } /// Tell LLVM whether it should optimise function for size. #[inline] #[allow(dead_code)] // possibly useful function pub fn set_optimize_for_size(val: ValueRef, optimize: bool) { - if optimize { - llvm::SetFunctionAttribute(val, llvm::Attribute::OptimizeForSize); - } else { - llvm::RemoveFunctionAttributes(val, llvm::Attribute::OptimizeForSize); - } + Attribute::OptimizeForSize.toggle_llfn(Function, val, optimize); } /// Tell LLVM if this function should be 'naked', i.e. skip the epilogue and prologue. #[inline] pub fn naked(val: ValueRef, is_naked: bool) { - if is_naked { - llvm::SetFunctionAttribute(val, llvm::Attribute::Naked); - } else { - llvm::RemoveFunctionAttributes(val, llvm::Attribute::Naked); - } + Attribute::Naked.toggle_llfn(Function, val, is_naked); } pub fn set_frame_pointer_elimination(ccx: &CrateContext, llfn: ValueRef) { // FIXME: #11906: Omitting frame pointers breaks retrieving the value of a // parameter. if ccx.sess().must_not_eliminate_frame_pointers() { - unsafe { - let attr = "no-frame-pointer-elim\0".as_ptr() as *const _; - let val = "true\0".as_ptr() as *const _; - llvm::LLVMRustAddFunctionAttrStringValue(llfn, - llvm::FunctionIndex as c_uint, - attr, - val); - } + llvm::AddFunctionAttrStringValue( + llfn, + llvm::AttributePlace::Function, + "no-frame-pointer-elim\0", + "true\0") } } @@ -98,13 +79,12 @@ pub fn from_fn_attrs(ccx: &CrateContext, attrs: &[ast::Attribute], llfn: ValueRe for attr in attrs { if attr.check_name("cold") { - llvm::Attributes::default().set(llvm::Attribute::Cold) - .apply_llfn(llvm::FunctionIndex as usize, llfn) + Attribute::Cold.apply_llfn(Function, llfn); } else if attr.check_name("naked") { naked(llfn, true); } else if attr.check_name("allocator") { - llvm::Attributes::default().set(llvm::Attribute::NoAlias) - .apply_llfn(llvm::ReturnIndex as usize, llfn) + Attribute::NoAlias.apply_llfn( + llvm::AttributePlace::ReturnValue(), llfn); } else if attr.check_name("unwind") { unwind(llfn, true); } diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index 3e66f6de242fd..7fb19fefee2d1 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -2347,9 +2347,9 @@ fn internalize_symbols<'a, 'tcx>(sess: &Session, let has_fixed_linkage = linkage_fixed_explicitly.contains(&name_cow); if !is_referenced_somewhere && !is_reachable && !has_fixed_linkage { - llvm::SetLinkage(val, llvm::InternalLinkage); - llvm::SetDLLStorageClass(val, - llvm::DLLStorageClassTypes::Default); + llvm::LLVMSetLinkage(val, llvm::InternalLinkage); + llvm::LLVMSetDLLStorageClass(val, + llvm::DLLStorageClass::Default); llvm::UnsetComdat(val); } } @@ -2394,7 +2394,7 @@ fn create_imps(cx: &CrateContextList) { imp_name.as_ptr() as *const _); let init = llvm::LLVMConstBitCast(val, i8p_ty.to_ref()); llvm::LLVMSetInitializer(imp, init); - llvm::SetLinkage(imp, llvm::ExternalLinkage); + llvm::LLVMSetLinkage(imp, llvm::ExternalLinkage); } } } diff --git a/src/librustc_trans/builder.rs b/src/librustc_trans/builder.rs index 28d69d4815fab..90f96af549691 100644 --- a/src/librustc_trans/builder.rs +++ b/src/librustc_trans/builder.rs @@ -841,7 +841,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let fty = Type::func(&argtys[..], &output); unsafe { let v = llvm::LLVMRustInlineAsm( - fty.to_ref(), asm, cons, volatile, alignstack, dia as c_uint); + fty.to_ref(), asm, cons, volatile, alignstack, dia); self.call(v, inputs, None) } } diff --git a/src/librustc_trans/closure.rs b/src/librustc_trans/closure.rs index 6b9de4a48786d..e53a5edfc6685 100644 --- a/src/librustc_trans/closure.rs +++ b/src/librustc_trans/closure.rs @@ -249,11 +249,13 @@ pub fn trans_closure_expr<'a, 'tcx>(dest: Dest<'a, 'tcx>, if !ccx.instances().borrow().contains_key(&instance) { let llfn = get_or_create_closure_declaration(ccx, closure_def_id, closure_substs); - if ccx.sess().target.target.options.allows_weak_linkage { - llvm::SetLinkage(llfn, llvm::WeakODRLinkage); - llvm::SetUniqueComdat(ccx.llmod(), llfn); - } else { - llvm::SetLinkage(llfn, llvm::InternalLinkage); + unsafe { + if ccx.sess().target.target.options.allows_weak_linkage { + llvm::LLVMSetLinkage(llfn, llvm::WeakODRLinkage); + llvm::SetUniqueComdat(ccx.llmod(), llfn); + } else { + llvm::LLVMSetLinkage(llfn, llvm::InternalLinkage); + } } // set an inline hint for all closures diff --git a/src/librustc_trans/common.rs b/src/librustc_trans/common.rs index 61d8a0837c1d6..a1783e9c0a382 100644 --- a/src/librustc_trans/common.rs +++ b/src/librustc_trans/common.rs @@ -980,7 +980,7 @@ pub fn C_cstr(cx: &CrateContext, s: InternedString, null_terminated: bool) -> Va }); llvm::LLVMSetInitializer(g, sc); llvm::LLVMSetGlobalConstant(g, True); - llvm::SetLinkage(g, llvm::InternalLinkage); + llvm::LLVMSetLinkage(g, llvm::InternalLinkage); cx.const_cstr_cache().borrow_mut().insert(s, g); g diff --git a/src/librustc_trans/consts.rs b/src/librustc_trans/consts.rs index 996efc9c1132f..7afb5257258ec 100644 --- a/src/librustc_trans/consts.rs +++ b/src/librustc_trans/consts.rs @@ -10,7 +10,7 @@ use llvm; -use llvm::{ConstFCmp, ConstICmp, SetLinkage, SetUnnamedAddr}; +use llvm::{SetUnnamedAddr}; use llvm::{InternalLinkage, ValueRef, Bool, True}; use middle::const_qualif::ConstQualif; use rustc_const_eval::{ConstEvalErr, lookup_const_fn_by_id, lookup_const_by_id, ErrKind}; @@ -125,7 +125,7 @@ pub fn addr_of_mut(ccx: &CrateContext, }); llvm::LLVMSetInitializer(gv, cv); llvm::LLVMSetAlignment(gv, align); - SetLinkage(gv, InternalLinkage); + llvm::LLVMSetLinkage(gv, InternalLinkage); SetUnnamedAddr(gv, true); gv } @@ -637,10 +637,10 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, hir::BiEq | hir::BiNe | hir::BiLt | hir::BiLe | hir::BiGt | hir::BiGe => { if is_float { let cmp = base::bin_op_to_fcmp_predicate(b.node); - ConstFCmp(cmp, te1, te2) + llvm::LLVMConstFCmp(cmp, te1, te2) } else { let cmp = base::bin_op_to_icmp_predicate(b.node, signed); - ConstICmp(cmp, te1, te2) + llvm::LLVMConstICmp(cmp, te1, te2) } }, } } // unsafe { match b.node { @@ -1072,7 +1072,7 @@ pub fn get_static<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, def_id: DefId) unsafe { // Declare a symbol `foo` with the desired linkage. let g1 = declare::declare_global(ccx, &sym, llty2); - llvm::SetLinkage(g1, linkage); + llvm::LLVMSetLinkage(g1, linkage); // Declare an internal global `extern_with_linkage_foo` which // is initialized with the address of `foo`. If `foo` is @@ -1086,7 +1086,7 @@ pub fn get_static<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, def_id: DefId) ccx.sess().span_fatal(span, &format!("symbol `{}` is already defined", &sym)) }); - llvm::SetLinkage(g2, llvm::InternalLinkage); + llvm::LLVMSetLinkage(g2, llvm::InternalLinkage); llvm::LLVMSetInitializer(g2, g1); g2 } @@ -1126,7 +1126,9 @@ pub fn get_static<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, def_id: DefId) } } if ccx.use_dll_storage_attrs() { - llvm::SetDLLStorageClass(g, llvm::DLLStorageClassTypes::DllImport); + unsafe { + llvm::LLVMSetDLLStorageClass(g, llvm::DLLStorageClass::DllImport); + } } g }; diff --git a/src/librustc_trans/debuginfo/gdb.rs b/src/librustc_trans/debuginfo/gdb.rs index cf312855d75bc..0a8d490dcd2dd 100644 --- a/src/librustc_trans/debuginfo/gdb.rs +++ b/src/librustc_trans/debuginfo/gdb.rs @@ -77,7 +77,7 @@ pub fn get_or_insert_gdb_debug_scripts_section_global(ccx: &CrateContext) llvm::LLVMSetInitializer(section_var, C_bytes(ccx, section_contents)); llvm::LLVMSetGlobalConstant(section_var, llvm::True); llvm::LLVMSetUnnamedAddr(section_var, llvm::True); - llvm::SetLinkage(section_var, llvm::Linkage::LinkOnceODRLinkage); + llvm::LLVMSetLinkage(section_var, llvm::Linkage::LinkOnceODRLinkage); // This should make sure that the whole section is not larger than // the string it contains. Otherwise we get a warning from GDB. llvm::LLVMSetAlignment(section_var, 1); diff --git a/src/librustc_trans/declare.rs b/src/librustc_trans/declare.rs index 15d90504ee7f0..324e8697ecae6 100644 --- a/src/librustc_trans/declare.rs +++ b/src/librustc_trans/declare.rs @@ -20,6 +20,7 @@ //! * Use define_* family of methods when you might be defining the ValueRef. //! * When in doubt, define. use llvm::{self, ValueRef}; +use llvm::AttributePlace::Function; use rustc::ty; use abi::{Abi, FnType}; use attributes; @@ -65,16 +66,16 @@ fn declare_raw_fn(ccx: &CrateContext, name: &str, callconv: llvm::CallConv, ty: if ccx.tcx().sess.opts.cg.no_redzone .unwrap_or(ccx.tcx().sess.target.target.options.disable_redzone) { - llvm::SetFunctionAttribute(llfn, llvm::Attribute::NoRedZone) + llvm::Attribute::NoRedZone.apply_llfn(Function, llfn); } match ccx.tcx().sess.opts.cg.opt_level.as_ref().map(String::as_ref) { Some("s") => { - llvm::SetFunctionAttribute(llfn, llvm::Attribute::OptimizeForSize); + llvm::Attribute::OptimizeForSize.apply_llfn(Function, llfn); }, Some("z") => { - llvm::SetFunctionAttribute(llfn, llvm::Attribute::MinSize); - llvm::SetFunctionAttribute(llfn, llvm::Attribute::OptimizeForSize); + llvm::Attribute::MinSize.apply_llfn(Function, llfn); + llvm::Attribute::OptimizeForSize.apply_llfn(Function, llfn); }, _ => {}, } @@ -111,7 +112,7 @@ pub fn declare_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, name: &str, let llfn = declare_raw_fn(ccx, name, fty.cconv, fty.llvm_type(ccx)); if sig.output == ty::FnDiverging { - llvm::SetFunctionAttribute(llfn, llvm::Attribute::NoReturn); + llvm::Attribute::NoReturn.apply_llfn(Function, llfn); } if abi != Abi::Rust && abi != Abi::RustCall { @@ -162,7 +163,7 @@ pub fn define_internal_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, name: &str, fn_type: ty::Ty<'tcx>) -> ValueRef { let llfn = define_fn(ccx, name, fn_type); - llvm::SetLinkage(llfn, llvm::InternalLinkage); + unsafe { llvm::LLVMSetLinkage(llfn, llvm::InternalLinkage) }; llfn } diff --git a/src/librustc_trans/mir/constant.rs b/src/librustc_trans/mir/constant.rs index 8dc5e5f993fbe..00db19d2739c3 100644 --- a/src/librustc_trans/mir/constant.rs +++ b/src/librustc_trans/mir/constant.rs @@ -824,11 +824,11 @@ pub fn const_scalar_binop(op: mir::BinOp, mir::BinOp::Gt | mir::BinOp::Ge => { if is_float { let cmp = base::bin_op_to_fcmp_predicate(op.to_hir_binop()); - llvm::ConstFCmp(cmp, lhs, rhs) + llvm::LLVMConstFCmp(cmp, lhs, rhs) } else { let cmp = base::bin_op_to_icmp_predicate(op.to_hir_binop(), signed); - llvm::ConstICmp(cmp, lhs, rhs) + llvm::LLVMConstICmp(cmp, lhs, rhs) } } } diff --git a/src/librustc_trans/monomorphize.rs b/src/librustc_trans/monomorphize.rs index 96a05f11bfd11..e9aacaa0f954f 100644 --- a/src/librustc_trans/monomorphize.rs +++ b/src/librustc_trans/monomorphize.rs @@ -125,7 +125,9 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, if ccx.shared().translation_items().borrow().contains(&trans_item) { attributes::from_fn_attrs(ccx, attrs, lldecl); - llvm::SetLinkage(lldecl, llvm::ExternalLinkage); + unsafe { + llvm::LLVMSetLinkage(lldecl, llvm::ExternalLinkage); + } } else { // FIXME: #34151 // Normally, getting here would indicate a bug in trans::collector, diff --git a/src/librustc_trans/trans_item.rs b/src/librustc_trans/trans_item.rs index fc2758e50f2ce..35bb0481c8e97 100644 --- a/src/librustc_trans/trans_item.rs +++ b/src/librustc_trans/trans_item.rs @@ -208,7 +208,7 @@ impl<'a, 'tcx> TransItem<'tcx> { &format!("symbol `{}` is already defined", symbol_name)) }); - llvm::SetLinkage(g, linkage); + unsafe { llvm::LLVMSetLinkage(g, linkage) }; } item => bug!("predefine_static: expected static, found {:?}", item) @@ -250,7 +250,7 @@ impl<'a, 'tcx> TransItem<'tcx> { ref attrs, node: hir::ImplItemKind::Method(..), .. }) => { let lldecl = declare::declare_fn(ccx, symbol_name, mono_ty); - llvm::SetLinkage(lldecl, linkage); + unsafe { llvm::LLVMSetLinkage(lldecl, linkage) }; base::set_link_section(ccx, lldecl, attrs); if linkage == llvm::LinkOnceODRLinkage || linkage == llvm::WeakODRLinkage { @@ -287,7 +287,7 @@ impl<'a, 'tcx> TransItem<'tcx> { assert!(declare::get_defined_value(ccx, symbol_name).is_none()); let llfn = declare::declare_cfn(ccx, symbol_name, llfnty); - llvm::SetLinkage(llfn, linkage); + unsafe { llvm::LLVMSetLinkage(llfn, linkage) }; if linkage == llvm::LinkOnceODRLinkage || linkage == llvm::WeakODRLinkage { llvm::SetUniqueComdat(ccx.llmod(), llfn); diff --git a/src/librustc_trans/type_.rs b/src/librustc_trans/type_.rs index c09515a51389a..d191591e082ad 100644 --- a/src/librustc_trans/type_.rs +++ b/src/librustc_trans/type_.rs @@ -208,7 +208,7 @@ impl Type { pub fn kind(&self) -> TypeKind { unsafe { - llvm::LLVMGetTypeKind(self.to_ref()) + llvm::LLVMRustGetTypeKind(self.to_ref()) } } diff --git a/src/rustllvm/ArchiveWrapper.cpp b/src/rustllvm/ArchiveWrapper.cpp index 059cc40d51144..1e873b5345c43 100644 --- a/src/rustllvm/ArchiveWrapper.cpp +++ b/src/rustllvm/ArchiveWrapper.cpp @@ -61,7 +61,7 @@ from_rust(LLVMRustArchiveKind kind) case LLVMRustArchiveKind::COFF: return Archive::K_COFF; default: - abort(); + llvm_unreachable("Bad ArchiveKind."); } } diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index 9e72724d8ab78..e3dcf45cf0fb5 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -196,7 +196,7 @@ from_rust(LLVMRustCodeModel model) case LLVMRustCodeModel::Large: return CodeModel::Large; default: - abort(); + llvm_unreachable("Bad CodeModel."); } } @@ -221,7 +221,7 @@ from_rust(LLVMRustCodeGenOptLevel level) case LLVMRustCodeGenOptLevel::Aggressive: return CodeGenOpt::Aggressive; default: - abort(); + llvm_unreachable("Bad CodeGenOptLevel."); } } @@ -395,7 +395,7 @@ from_rust(LLVMRustFileType type) case LLVMRustFileType::ObjectFile: return TargetMachine::CGFT_ObjectFile; default: - abort(); + llvm_unreachable("Bad FileType."); } } diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index a9c31bc33e073..0da25e7ac57b7 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -263,7 +263,7 @@ from_rust(LLVMRustSynchronizationScope scope) case LLVMRustSynchronizationScope::CrossThread: return CrossThread; default: - abort(); + llvm_unreachable("bad SynchronizationScope."); } } @@ -281,15 +281,34 @@ extern "C" void LLVMRustSetDebug(int Enabled) { #endif } +enum class LLVMRustAsmDialect { + Other, + Att, + Intel, +}; + +static InlineAsm::AsmDialect +from_rust(LLVMRustAsmDialect dialect) +{ + switch (dialect) { + case LLVMRustAsmDialect::Att: + return InlineAsm::AD_ATT; + case LLVMRustAsmDialect::Intel: + return InlineAsm::AD_Intel; + default: + llvm_unreachable("bad AsmDialect."); + } +} + extern "C" LLVMValueRef LLVMRustInlineAsm(LLVMTypeRef Ty, char *AsmString, char *Constraints, LLVMBool HasSideEffects, LLVMBool IsAlignStack, - unsigned Dialect) { + LLVMRustAsmDialect Dialect) { return wrap(InlineAsm::get(unwrap(Ty), AsmString, Constraints, HasSideEffects, - IsAlignStack, (InlineAsm::AsmDialect) Dialect)); + IsAlignStack, from_rust(Dialect))); } typedef DIBuilder* LLVMRustDIBuilderRef; @@ -797,35 +816,6 @@ LLVMRustLinkInExternalBitcode(LLVMModuleRef dst, char *bc, size_t len) { return true; } -enum class LLVMRustDLLStorageClassTypes { - Other, - Default, - DllImport, - DllExport, -}; - -static GlobalValue::DLLStorageClassTypes -from_rust(LLVMRustDLLStorageClassTypes Class) -{ - switch (Class) { - case LLVMRustDLLStorageClassTypes::Default: - return GlobalValue::DefaultStorageClass; - case LLVMRustDLLStorageClassTypes::DllImport: - return GlobalValue::DLLImportStorageClass; - case LLVMRustDLLStorageClassTypes::DllExport: - return GlobalValue::DLLExportStorageClass; - default: - abort(); - } -} - -extern "C" void -LLVMRustSetDLLStorageClass(LLVMValueRef Value, - LLVMRustDLLStorageClassTypes Class) { - GlobalValue *V = unwrap(Value); - V->setDLLStorageClass(from_rust(Class)); -} - // Note that the two following functions look quite similar to the // LLVMGetSectionName function. Sadly, it appears that this function only // returns a char* pointer, which isn't guaranteed to be null-terminated. The @@ -955,10 +945,53 @@ to_rust(DiagnosticKind kind) } } - extern "C" LLVMRustDiagnosticKind LLVMRustGetDiagInfoKind(LLVMDiagnosticInfoRef di) { return to_rust((DiagnosticKind) unwrap(di)->getKind()); } +// This is kept distinct from LLVMGetTypeKind, because when +// a new type kind is added, the Rust-side enum must be +// updated or UB will result. +extern "C" LLVMTypeKind LLVMRustGetTypeKind(LLVMTypeRef Ty) { + switch (unwrap(Ty)->getTypeID()) { + case Type::VoidTyID: + return LLVMVoidTypeKind; + case Type::HalfTyID: + return LLVMHalfTypeKind; + case Type::FloatTyID: + return LLVMFloatTypeKind; + case Type::DoubleTyID: + return LLVMDoubleTypeKind; + case Type::X86_FP80TyID: + return LLVMX86_FP80TypeKind; + case Type::FP128TyID: + return LLVMFP128TypeKind; + case Type::PPC_FP128TyID: + return LLVMPPC_FP128TypeKind; + case Type::LabelTyID: + return LLVMLabelTypeKind; + case Type::MetadataTyID: + return LLVMMetadataTypeKind; + case Type::IntegerTyID: + return LLVMIntegerTypeKind; + case Type::FunctionTyID: + return LLVMFunctionTypeKind; + case Type::StructTyID: + return LLVMStructTypeKind; + case Type::ArrayTyID: + return LLVMArrayTypeKind; + case Type::PointerTyID: + return LLVMPointerTypeKind; + case Type::VectorTyID: + return LLVMVectorTypeKind; + case Type::X86_MMXTyID: + return LLVMX86_MMXTypeKind; +#if LLVM_VERSION_MINOR >= 8 + case Type::TokenTyID: + return LLVMTokenTypeKind; +#endif + } + llvm_unreachable("Unhandled TypeID."); +} extern "C" void LLVMRustWriteDebugLocToString( LLVMContextRef C, @@ -971,7 +1004,6 @@ extern "C" void LLVMRustWriteDebugLocToString( DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SMDiagnostic, LLVMSMDiagnosticRef) -// FIXME(type-audit): assume this function-pointer type does not change extern "C" void LLVMRustSetInlineAsmDiagnosticHandler( LLVMContextRef C, LLVMContext::InlineAsmDiagHandlerTy H, @@ -1028,8 +1060,6 @@ LLVMRustBuildCleanupRet(LLVMBuilderRef Builder, #endif } -// FIXME: to here. - extern "C" LLVMValueRef LLVMRustBuildCatchPad(LLVMBuilderRef Builder, LLVMValueRef ParentPad,