finish type-auditing rustllvm

This commit is contained in:
Ariel Ben-Yehuda 2016-08-03 00:25:19 +03:00 committed by Ariel Ben-Yehuda
parent 24874170b4
commit 3041a97b1a
19 changed files with 247 additions and 195 deletions

View File

@ -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;

View File

@ -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 SetFunctionAttribute(fn_: ValueRef, attr: Attribute) {
unsafe {
LLVMRustAddFunctionAttribute(fn_, FunctionIndex as c_uint,
attr.bits() as u64)
pub fn apply_callsite(&self, idx: AttributePlace, callsite: ValueRef) {
unsafe {
LLVMRustAddCallSiteAttribute(
callsite, 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 unapply_llfn(&self, idx: AttributePlace, llfn: ValueRef) {
unsafe {
LLVMRustRemoveFunctionAttributes(
llfn, idx.as_uint(), self.bits())
}
}
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. */

View File

@ -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;
}
}

View File

@ -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();

View File

@ -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);
}

View File

@ -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);
}
}
}

View File

@ -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)
}
}

View File

@ -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

View File

@ -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

View File

@ -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
};

View File

@ -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);

View File

@ -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
}

View File

@ -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)
}
}
}

View File

@ -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,

View File

@ -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);

View File

@ -208,7 +208,7 @@ impl Type {
pub fn kind(&self) -> TypeKind {
unsafe {
llvm::LLVMGetTypeKind(self.to_ref())
llvm::LLVMRustGetTypeKind(self.to_ref())
}
}

View File

@ -61,7 +61,7 @@ from_rust(LLVMRustArchiveKind kind)
case LLVMRustArchiveKind::COFF:
return Archive::K_COFF;
default:
abort();
llvm_unreachable("Bad ArchiveKind.");
}
}

View File

@ -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.");
}
}

View File

@ -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<FunctionType>(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<GlobalValue>(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,