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