diff options
| author | Irina Popa <irinagpopa@gmail.com> | 2018-05-29 20:41:36 +0300 |
|---|---|---|
| committer | Irina Popa <irinagpopa@gmail.com> | 2018-07-30 18:03:50 +0300 |
| commit | 077be49bde25ca92dc03c86c805438609133a82a (patch) | |
| tree | afae5c5f1b8aab0a7a6bc3ef5ff1394154af20de /src/librustc_codegen_llvm/llvm | |
| parent | 54628c8ea844956f3f4f416b82067c634eb09f7b (diff) | |
| download | rust-077be49bde25ca92dc03c86c805438609133a82a.tar.gz rust-077be49bde25ca92dc03c86c805438609133a82a.zip | |
rustc_llvm: move to rustc_codegen_llvm::llvm.
Diffstat (limited to 'src/librustc_codegen_llvm/llvm')
| -rw-r--r-- | src/librustc_codegen_llvm/llvm/archive_ro.rs | 150 | ||||
| -rw-r--r-- | src/librustc_codegen_llvm/llvm/diagnostic.rs | 171 | ||||
| -rw-r--r-- | src/librustc_codegen_llvm/llvm/ffi.rs | 1795 | ||||
| -rw-r--r-- | src/librustc_codegen_llvm/llvm/mod.rs | 315 |
4 files changed, 2431 insertions, 0 deletions
diff --git a/src/librustc_codegen_llvm/llvm/archive_ro.rs b/src/librustc_codegen_llvm/llvm/archive_ro.rs new file mode 100644 index 00000000000..116f16de324 --- /dev/null +++ b/src/librustc_codegen_llvm/llvm/archive_ro.rs @@ -0,0 +1,150 @@ +// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! A wrapper around LLVM's archive (.a) code + +use super::ArchiveRef; + +use std::ffi::CString; +use std::marker; +use std::path::Path; +use std::slice; +use std::str; + +pub struct ArchiveRO { + ptr: ArchiveRef, +} + +unsafe impl Send for ArchiveRO {} + +pub struct Iter<'a> { + archive: &'a ArchiveRO, + ptr: super::ArchiveIteratorRef, +} + +pub struct Child<'a> { + ptr: super::ArchiveChildRef, + _data: marker::PhantomData<&'a ArchiveRO>, +} + +impl ArchiveRO { + /// Opens a static archive for read-only purposes. This is more optimized + /// than the `open` method because it uses LLVM's internal `Archive` class + /// rather than shelling out to `ar` for everything. + /// + /// If this archive is used with a mutable method, then an error will be + /// raised. + pub fn open(dst: &Path) -> Result<ArchiveRO, String> { + return unsafe { + let s = path2cstr(dst); + let ar = super::LLVMRustOpenArchive(s.as_ptr()); + if ar.is_null() { + Err(super::last_error().unwrap_or("failed to open archive".to_string())) + } else { + Ok(ArchiveRO { ptr: ar }) + } + }; + + #[cfg(unix)] + fn path2cstr(p: &Path) -> CString { + use std::os::unix::prelude::*; + use std::ffi::OsStr; + let p: &OsStr = p.as_ref(); + CString::new(p.as_bytes()).unwrap() + } + #[cfg(windows)] + fn path2cstr(p: &Path) -> CString { + CString::new(p.to_str().unwrap()).unwrap() + } + } + + pub fn raw(&self) -> ArchiveRef { + self.ptr + } + + pub fn iter(&self) -> Iter { + unsafe { + Iter { + ptr: super::LLVMRustArchiveIteratorNew(self.ptr), + archive: self, + } + } + } +} + +impl Drop for ArchiveRO { + fn drop(&mut self) { + unsafe { + super::LLVMRustDestroyArchive(self.ptr); + } + } +} + +impl<'a> Iterator for Iter<'a> { + type Item = Result<Child<'a>, String>; + + fn next(&mut self) -> Option<Result<Child<'a>, String>> { + let ptr = unsafe { super::LLVMRustArchiveIteratorNext(self.ptr) }; + if ptr.is_null() { + super::last_error().map(Err) + } else { + Some(Ok(Child { + ptr, + _data: marker::PhantomData, + })) + } + } +} + +impl<'a> Drop for Iter<'a> { + fn drop(&mut self) { + unsafe { + super::LLVMRustArchiveIteratorFree(self.ptr); + } + } +} + +impl<'a> Child<'a> { + pub fn name(&self) -> Option<&'a str> { + unsafe { + let mut name_len = 0; + let name_ptr = super::LLVMRustArchiveChildName(self.ptr, &mut name_len); + if name_ptr.is_null() { + None + } else { + let name = slice::from_raw_parts(name_ptr as *const u8, name_len as usize); + str::from_utf8(name).ok().map(|s| s.trim()) + } + } + } + + pub fn data(&self) -> &'a [u8] { + unsafe { + let mut data_len = 0; + let data_ptr = super::LLVMRustArchiveChildData(self.ptr, &mut data_len); + if data_ptr.is_null() { + panic!("failed to read data from archive child"); + } + slice::from_raw_parts(data_ptr as *const u8, data_len as usize) + } + } + + pub fn raw(&self) -> super::ArchiveChildRef { + self.ptr + } +} + +impl<'a> Drop for Child<'a> { + fn drop(&mut self) { + unsafe { + super::LLVMRustArchiveChildFree(self.ptr); + } + } +} diff --git a/src/librustc_codegen_llvm/llvm/diagnostic.rs b/src/librustc_codegen_llvm/llvm/diagnostic.rs new file mode 100644 index 00000000000..0674bccd51e --- /dev/null +++ b/src/librustc_codegen_llvm/llvm/diagnostic.rs @@ -0,0 +1,171 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! LLVM diagnostic reports. + +pub use self::OptimizationDiagnosticKind::*; +pub use self::Diagnostic::*; + +use libc::c_uint; +use std::ptr; + +use super::{DiagnosticInfoRef, TwineRef, ValueRef}; + +#[derive(Copy, Clone)] +pub enum OptimizationDiagnosticKind { + OptimizationRemark, + OptimizationMissed, + OptimizationAnalysis, + OptimizationAnalysisFPCommute, + OptimizationAnalysisAliasing, + OptimizationFailure, + OptimizationRemarkOther, +} + +impl OptimizationDiagnosticKind { + pub fn describe(self) -> &'static str { + match self { + OptimizationRemark | OptimizationRemarkOther => "remark", + OptimizationMissed => "missed", + OptimizationAnalysis => "analysis", + OptimizationAnalysisFPCommute => "floating-point", + OptimizationAnalysisAliasing => "aliasing", + OptimizationFailure => "failure", + } + } +} + +pub struct OptimizationDiagnostic { + pub kind: OptimizationDiagnosticKind, + pub pass_name: String, + pub function: ValueRef, + pub line: c_uint, + pub column: c_uint, + pub filename: String, + pub message: String, +} + +impl OptimizationDiagnostic { + unsafe fn unpack(kind: OptimizationDiagnosticKind, + di: DiagnosticInfoRef) + -> OptimizationDiagnostic { + let mut function = ptr::null_mut(); + let mut line = 0; + let mut column = 0; + + let mut message = None; + let mut filename = None; + let pass_name = super::build_string(|pass_name| + message = super::build_string(|message| + filename = super::build_string(|filename| + super::LLVMRustUnpackOptimizationDiagnostic(di, + pass_name, + &mut function, + &mut line, + &mut column, + filename, + message) + ) + ) + ); + + let mut filename = filename.unwrap_or(String::new()); + if filename.is_empty() { + filename.push_str("<unknown file>"); + } + + OptimizationDiagnostic { + kind, + pass_name: pass_name.expect("got a non-UTF8 pass name from LLVM"), + function, + line, + column, + filename, + message: message.expect("got a non-UTF8 OptimizationDiagnostic message from LLVM") + } + } +} + +#[derive(Copy, Clone)] +pub struct InlineAsmDiagnostic { + pub cookie: c_uint, + pub message: TwineRef, + pub instruction: ValueRef, +} + +impl InlineAsmDiagnostic { + unsafe fn unpack(di: DiagnosticInfoRef) -> InlineAsmDiagnostic { + + let mut opt = InlineAsmDiagnostic { + cookie: 0, + message: ptr::null_mut(), + instruction: ptr::null_mut(), + }; + + super::LLVMRustUnpackInlineAsmDiagnostic(di, + &mut opt.cookie, + &mut opt.message, + &mut opt.instruction); + + opt + } +} + +pub enum Diagnostic { + Optimization(OptimizationDiagnostic), + InlineAsm(InlineAsmDiagnostic), + PGO(DiagnosticInfoRef), + + /// LLVM has other types that we do not wrap here. + UnknownDiagnostic(DiagnosticInfoRef), +} + +impl Diagnostic { + pub unsafe fn unpack(di: DiagnosticInfoRef) -> Diagnostic { + use super::DiagnosticKind as Dk; + let kind = super::LLVMRustGetDiagInfoKind(di); + + match kind { + Dk::InlineAsm => InlineAsm(InlineAsmDiagnostic::unpack(di)), + + Dk::OptimizationRemark => { + Optimization(OptimizationDiagnostic::unpack(OptimizationRemark, di)) + } + Dk::OptimizationRemarkOther => { + Optimization(OptimizationDiagnostic::unpack(OptimizationRemarkOther, di)) + } + Dk::OptimizationRemarkMissed => { + Optimization(OptimizationDiagnostic::unpack(OptimizationMissed, di)) + } + + Dk::OptimizationRemarkAnalysis => { + Optimization(OptimizationDiagnostic::unpack(OptimizationAnalysis, di)) + } + + Dk::OptimizationRemarkAnalysisFPCommute => { + Optimization(OptimizationDiagnostic::unpack(OptimizationAnalysisFPCommute, di)) + } + + Dk::OptimizationRemarkAnalysisAliasing => { + Optimization(OptimizationDiagnostic::unpack(OptimizationAnalysisAliasing, di)) + } + + Dk::OptimizationFailure => { + Optimization(OptimizationDiagnostic::unpack(OptimizationFailure, di)) + } + + Dk::PGOProfile => { + PGO(di) + } + + _ => UnknownDiagnostic(di), + } + } +} diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs new file mode 100644 index 00000000000..afd1070a77e --- /dev/null +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -0,0 +1,1795 @@ +// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// FIXME: Rename 'DIGlobalVariable' to 'DIGlobalVariableExpression' +// once support for LLVM 3.9 is dropped. +// +// This method was changed in this LLVM patch: +// https://reviews.llvm.org/D26769 + +use super::debuginfo::{ + DIBuilderRef, DIDescriptor, DIFile, DILexicalBlock, DISubprogram, DIType, + DIBasicType, DIDerivedType, DICompositeType, DIScope, DIVariable, + DIGlobalVariable, DIArray, DISubrange, DITemplateTypeParameter, DIEnumerator, + DINameSpace, DIFlags, +}; + +use libc::{c_uint, c_int, size_t, c_char}; +use libc::{c_longlong, c_ulonglong, c_void}; + +use super::RustStringRef; + +pub type Opcode = u32; +pub type Bool = c_uint; + +pub const True: Bool = 1 as Bool; +pub const False: Bool = 0 as Bool; + +#[derive(Copy, Clone, PartialEq)] +#[repr(C)] +pub enum LLVMRustResult { + Success, + Failure, +} +// Consts for the LLVM CallConv type, pre-cast to usize. + +/// LLVM CallingConv::ID. Should we wrap this? +#[derive(Copy, Clone, PartialEq, Debug)] +#[repr(C)] +pub enum CallConv { + CCallConv = 0, + FastCallConv = 8, + ColdCallConv = 9, + X86StdcallCallConv = 64, + X86FastcallCallConv = 65, + ArmAapcsCallConv = 67, + Msp430Intr = 69, + X86_ThisCall = 70, + PtxKernel = 71, + X86_64_SysV = 78, + X86_64_Win64 = 79, + X86_VectorCall = 80, + X86_Intr = 83, + AmdGpuKernel = 91, +} + +/// LLVMRustLinkage +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] +#[repr(C)] +pub enum Linkage { + ExternalLinkage = 0, + AvailableExternallyLinkage = 1, + LinkOnceAnyLinkage = 2, + LinkOnceODRLinkage = 3, + WeakAnyLinkage = 4, + WeakODRLinkage = 5, + AppendingLinkage = 6, + InternalLinkage = 7, + PrivateLinkage = 8, + ExternalWeakLinkage = 9, + CommonLinkage = 10, +} + +// LLVMRustVisibility +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] +#[repr(C)] +pub enum Visibility { + Default = 0, + Hidden = 1, + Protected = 2, +} + +/// LLVMDiagnosticSeverity +#[derive(Copy, Clone, Debug)] +#[repr(C)] +pub enum DiagnosticSeverity { + Error = 0, + Warning = 1, + Remark = 2, + Note = 3, +} + +/// LLVMDLLStorageClass +#[derive(Copy, Clone)] +#[repr(C)] +pub enum DLLStorageClass { + Default = 0, + DllImport = 1, // Function to be imported from DLL. + DllExport = 2, // Function to be accessible from DLL. +} + +/// Matches LLVMRustAttribute in rustllvm.h +/// Semantically a subset of the C++ enum llvm::Attribute::AttrKind, +/// though it is not ABI compatible (since it's a C++ enum) +#[repr(C)] +#[derive(Copy, Clone, Debug)] +pub enum Attribute { + AlwaysInline = 0, + ByVal = 1, + Cold = 2, + InlineHint = 3, + MinSize = 4, + Naked = 5, + NoAlias = 6, + NoCapture = 7, + NoInline = 8, + NonNull = 9, + NoRedZone = 10, + NoReturn = 11, + NoUnwind = 12, + OptimizeForSize = 13, + ReadOnly = 14, + SExt = 15, + StructRet = 16, + UWTable = 17, + ZExt = 18, + InReg = 19, + SanitizeThread = 20, + SanitizeAddress = 21, + SanitizeMemory = 22, +} + +/// LLVMIntPredicate +#[derive(Copy, Clone)] +#[repr(C)] +pub enum IntPredicate { + IntEQ = 32, + IntNE = 33, + IntUGT = 34, + IntUGE = 35, + IntULT = 36, + IntULE = 37, + IntSGT = 38, + IntSGE = 39, + IntSLT = 40, + IntSLE = 41, +} + +/// LLVMRealPredicate +#[derive(Copy, Clone)] +#[repr(C)] +pub enum RealPredicate { + RealPredicateFalse = 0, + RealOEQ = 1, + RealOGT = 2, + RealOGE = 3, + RealOLT = 4, + RealOLE = 5, + RealONE = 6, + RealORD = 7, + RealUNO = 8, + RealUEQ = 9, + RealUGT = 10, + RealUGE = 11, + RealULT = 12, + RealULE = 13, + RealUNE = 14, + RealPredicateTrue = 15, +} + +/// LLVMTypeKind +#[derive(Copy, Clone, PartialEq, Debug)] +#[repr(C)] +pub enum TypeKind { + Void = 0, + Half = 1, + Float = 2, + Double = 3, + X86_FP80 = 4, + FP128 = 5, + PPC_FP128 = 6, + Label = 7, + Integer = 8, + Function = 9, + Struct = 10, + Array = 11, + Pointer = 12, + Vector = 13, + Metadata = 14, + X86_MMX = 15, + Token = 16, +} + +/// LLVMAtomicRmwBinOp +#[derive(Copy, Clone)] +#[repr(C)] +pub enum AtomicRmwBinOp { + AtomicXchg = 0, + AtomicAdd = 1, + AtomicSub = 2, + AtomicAnd = 3, + AtomicNand = 4, + AtomicOr = 5, + AtomicXor = 6, + AtomicMax = 7, + AtomicMin = 8, + AtomicUMax = 9, + AtomicUMin = 10, +} + +/// LLVMAtomicOrdering +#[derive(Copy, Clone)] +#[repr(C)] +pub enum AtomicOrdering { + NotAtomic = 0, + Unordered = 1, + Monotonic = 2, + // Consume = 3, // Not specified yet. + Acquire = 4, + Release = 5, + AcquireRelease = 6, + SequentiallyConsistent = 7, +} + +/// LLVMRustSynchronizationScope +#[derive(Copy, Clone)] +#[repr(C)] +pub enum SynchronizationScope { + Other, + SingleThread, + CrossThread, +} + +/// LLVMRustFileType +#[derive(Copy, Clone)] +#[repr(C)] +pub enum FileType { + Other, + AssemblyFile, + ObjectFile, +} + +/// LLVMMetadataType +#[derive(Copy, Clone)] +#[repr(C)] +pub enum MetadataType { + MD_dbg = 0, + MD_tbaa = 1, + MD_prof = 2, + MD_fpmath = 3, + MD_range = 4, + MD_tbaa_struct = 5, + MD_invariant_load = 6, + MD_alias_scope = 7, + MD_noalias = 8, + MD_nontemporal = 9, + MD_mem_parallel_loop_access = 10, + MD_nonnull = 11, +} + +/// LLVMRustAsmDialect +#[derive(Copy, Clone)] +#[repr(C)] +pub enum AsmDialect { + Other, + Att, + Intel, +} + +/// LLVMRustCodeGenOptLevel +#[derive(Copy, Clone, PartialEq)] +#[repr(C)] +pub enum CodeGenOptLevel { + Other, + None, + Less, + Default, + Aggressive, +} + +/// LLVMRelocMode +#[derive(Copy, Clone, PartialEq)] +#[repr(C)] +pub enum RelocMode { + Default, + Static, + PIC, + DynamicNoPic, + ROPI, + RWPI, + ROPI_RWPI, +} + +/// LLVMRustCodeModel +#[derive(Copy, Clone)] +#[repr(C)] +pub enum CodeModel { + Other, + Small, + Kernel, + Medium, + Large, + None, +} + +/// LLVMRustDiagnosticKind +#[derive(Copy, Clone)] +#[repr(C)] +pub enum DiagnosticKind { + Other, + InlineAsm, + StackSize, + DebugMetadataVersion, + SampleProfile, + OptimizationRemark, + OptimizationRemarkMissed, + OptimizationRemarkAnalysis, + OptimizationRemarkAnalysisFPCommute, + OptimizationRemarkAnalysisAliasing, + OptimizationRemarkOther, + OptimizationFailure, + PGOProfile, +} + +/// LLVMRustArchiveKind +#[derive(Copy, Clone)] +#[repr(C)] +pub enum ArchiveKind { + Other, + K_GNU, + K_BSD, + K_COFF, +} + +/// LLVMRustPassKind +#[derive(Copy, Clone, PartialEq, Debug)] +#[repr(C)] +pub enum PassKind { + Other, + Function, + Module, +} + +/// LLVMRustThinLTOData +pub enum ThinLTOData {} + +/// LLVMRustThinLTOBuffer +pub enum ThinLTOBuffer {} + +/// LLVMRustThinLTOModule +#[repr(C)] +pub struct ThinLTOModule { + pub identifier: *const c_char, + pub data: *const u8, + pub len: usize, +} + +/// LLVMThreadLocalMode +#[derive(Copy, Clone)] +#[repr(C)] +pub enum ThreadLocalMode { + NotThreadLocal, + GeneralDynamic, + LocalDynamic, + InitialExec, + LocalExec +} + +// Opaque pointer types +#[allow(missing_copy_implementations)] +pub enum Module_opaque {} +pub type ModuleRef = *mut Module_opaque; +#[allow(missing_copy_implementations)] +pub enum Context_opaque {} +pub type ContextRef = *mut Context_opaque; +#[allow(missing_copy_implementations)] +pub enum Type_opaque {} +pub type TypeRef = *mut Type_opaque; +#[allow(missing_copy_implementations)] +pub enum Value_opaque {} +pub type ValueRef = *mut Value_opaque; +#[allow(missing_copy_implementations)] +pub enum Metadata_opaque {} +pub type MetadataRef = *mut Metadata_opaque; +#[allow(missing_copy_implementations)] +pub enum BasicBlock_opaque {} +pub type BasicBlockRef = *mut BasicBlock_opaque; +#[allow(missing_copy_implementations)] +pub enum Builder_opaque {} +pub type BuilderRef = *mut Builder_opaque; +#[allow(missing_copy_implementations)] +pub enum ExecutionEngine_opaque {} +pub type ExecutionEngineRef = *mut ExecutionEngine_opaque; +#[allow(missing_copy_implementations)] +pub enum MemoryBuffer_opaque {} +pub type MemoryBufferRef = *mut MemoryBuffer_opaque; +#[allow(missing_copy_implementations)] +pub enum PassManager_opaque {} +pub type PassManagerRef = *mut PassManager_opaque; +#[allow(missing_copy_implementations)] +pub enum PassManagerBuilder_opaque {} +pub type PassManagerBuilderRef = *mut PassManagerBuilder_opaque; +#[allow(missing_copy_implementations)] +pub enum Use_opaque {} +pub type UseRef = *mut Use_opaque; +#[allow(missing_copy_implementations)] +pub enum TargetData_opaque {} +pub type TargetDataRef = *mut TargetData_opaque; +#[allow(missing_copy_implementations)] +pub enum ObjectFile_opaque {} +pub type ObjectFileRef = *mut ObjectFile_opaque; +#[allow(missing_copy_implementations)] +pub enum SectionIterator_opaque {} +pub type SectionIteratorRef = *mut SectionIterator_opaque; +#[allow(missing_copy_implementations)] +pub enum Pass_opaque {} +pub type PassRef = *mut Pass_opaque; +#[allow(missing_copy_implementations)] +pub enum TargetMachine_opaque {} +pub type TargetMachineRef = *mut TargetMachine_opaque; +pub enum Archive_opaque {} +pub type ArchiveRef = *mut Archive_opaque; +pub enum ArchiveIterator_opaque {} +pub type ArchiveIteratorRef = *mut ArchiveIterator_opaque; +pub enum ArchiveChild_opaque {} +pub type ArchiveChildRef = *mut ArchiveChild_opaque; +#[allow(missing_copy_implementations)] +pub enum Twine_opaque {} +pub type TwineRef = *mut Twine_opaque; +#[allow(missing_copy_implementations)] +pub enum DiagnosticInfo_opaque {} +pub type DiagnosticInfoRef = *mut DiagnosticInfo_opaque; +#[allow(missing_copy_implementations)] +pub enum DebugLoc_opaque {} +pub type DebugLocRef = *mut DebugLoc_opaque; +#[allow(missing_copy_implementations)] +pub enum SMDiagnostic_opaque {} +pub type SMDiagnosticRef = *mut SMDiagnostic_opaque; +#[allow(missing_copy_implementations)] +pub enum RustArchiveMember_opaque {} +pub type RustArchiveMemberRef = *mut RustArchiveMember_opaque; +#[allow(missing_copy_implementations)] +pub enum OperandBundleDef_opaque {} +pub type OperandBundleDefRef = *mut OperandBundleDef_opaque; +#[allow(missing_copy_implementations)] +pub enum Linker_opaque {} +pub type LinkerRef = *mut Linker_opaque; + +pub type DiagnosticHandler = unsafe extern "C" fn(DiagnosticInfoRef, *mut c_void); +pub type InlineAsmDiagHandler = unsafe extern "C" fn(SMDiagnosticRef, *const c_void, c_uint); + + +pub mod debuginfo { + use super::MetadataRef; + + #[allow(missing_copy_implementations)] + pub enum DIBuilder_opaque {} + pub type DIBuilderRef = *mut DIBuilder_opaque; + + pub type DIDescriptor = MetadataRef; + pub type DIScope = DIDescriptor; + pub type DILocation = DIDescriptor; + pub type DIFile = DIScope; + pub type DILexicalBlock = DIScope; + pub type DISubprogram = DIScope; + pub type DINameSpace = DIScope; + pub type DIType = DIDescriptor; + pub type DIBasicType = DIType; + pub type DIDerivedType = DIType; + pub type DICompositeType = DIDerivedType; + pub type DIVariable = DIDescriptor; + pub type DIGlobalVariable = DIDescriptor; + pub type DIArray = DIDescriptor; + pub type DISubrange = DIDescriptor; + pub type DIEnumerator = DIDescriptor; + pub type DITemplateTypeParameter = DIDescriptor; + + // These values **must** match with LLVMRustDIFlags!! + bitflags! { + #[repr(C)] + #[derive(Default)] + pub struct DIFlags: ::libc::uint32_t { + const FlagZero = 0; + const FlagPrivate = 1; + const FlagProtected = 2; + const FlagPublic = 3; + const FlagFwdDecl = (1 << 2); + const FlagAppleBlock = (1 << 3); + const FlagBlockByrefStruct = (1 << 4); + const FlagVirtual = (1 << 5); + const FlagArtificial = (1 << 6); + const FlagExplicit = (1 << 7); + const FlagPrototyped = (1 << 8); + const FlagObjcClassComplete = (1 << 9); + const FlagObjectPointer = (1 << 10); + const FlagVector = (1 << 11); + const FlagStaticMember = (1 << 12); + const FlagLValueReference = (1 << 13); + const FlagRValueReference = (1 << 14); + const FlagExternalTypeRef = (1 << 15); + const FlagIntroducedVirtual = (1 << 18); + const FlagBitField = (1 << 19); + const FlagNoReturn = (1 << 20); + const FlagMainSubprogram = (1 << 21); + } + } +} + +pub enum ModuleBuffer {} + +extern "C" { + // Create and destroy contexts. + pub fn LLVMRustContextCreate(shouldDiscardNames: bool) -> ContextRef; + pub fn LLVMContextDispose(C: ContextRef); + pub fn LLVMGetMDKindIDInContext(C: ContextRef, Name: *const c_char, SLen: c_uint) -> c_uint; + + // Create and destroy modules. + pub fn LLVMModuleCreateWithNameInContext(ModuleID: *const c_char, C: ContextRef) -> ModuleRef; + pub fn LLVMGetModuleContext(M: ModuleRef) -> ContextRef; + pub fn LLVMCloneModule(M: ModuleRef) -> ModuleRef; + pub fn LLVMDisposeModule(M: ModuleRef); + + /// Data layout. See Module::getDataLayout. + pub fn LLVMGetDataLayout(M: ModuleRef) -> *const c_char; + pub fn LLVMSetDataLayout(M: ModuleRef, Triple: *const c_char); + + /// See Module::dump. + pub fn LLVMDumpModule(M: ModuleRef); + + /// See Module::setModuleInlineAsm. + pub fn LLVMSetModuleInlineAsm(M: ModuleRef, Asm: *const c_char); + pub fn LLVMRustAppendModuleInlineAsm(M: ModuleRef, Asm: *const c_char); + + /// See llvm::LLVMTypeKind::getTypeID. + pub fn LLVMRustGetTypeKind(Ty: TypeRef) -> TypeKind; + + // Operations on integer types + pub fn LLVMInt1TypeInContext(C: ContextRef) -> TypeRef; + pub fn LLVMInt8TypeInContext(C: ContextRef) -> TypeRef; + pub fn LLVMInt16TypeInContext(C: ContextRef) -> TypeRef; + pub fn LLVMInt32TypeInContext(C: ContextRef) -> TypeRef; + pub fn LLVMInt64TypeInContext(C: ContextRef) -> TypeRef; + pub fn LLVMIntTypeInContext(C: ContextRef, NumBits: c_uint) -> TypeRef; + + pub fn LLVMGetIntTypeWidth(IntegerTy: TypeRef) -> c_uint; + + // Operations on real types + pub fn LLVMFloatTypeInContext(C: ContextRef) -> TypeRef; + pub fn LLVMDoubleTypeInContext(C: ContextRef) -> TypeRef; + + // Operations on function types + pub fn LLVMFunctionType(ReturnType: TypeRef, + ParamTypes: *const TypeRef, + ParamCount: c_uint, + IsVarArg: Bool) + -> TypeRef; + pub fn LLVMGetReturnType(FunctionTy: TypeRef) -> TypeRef; + pub fn LLVMCountParamTypes(FunctionTy: TypeRef) -> c_uint; + pub fn LLVMGetParamTypes(FunctionTy: TypeRef, Dest: *mut TypeRef); + + // Operations on struct types + pub fn LLVMStructTypeInContext(C: ContextRef, + ElementTypes: *const TypeRef, + ElementCount: c_uint, + Packed: Bool) + -> TypeRef; + pub fn LLVMIsPackedStruct(StructTy: TypeRef) -> Bool; + + // Operations on array, pointer, and vector types (sequence types) + pub fn LLVMRustArrayType(ElementType: TypeRef, ElementCount: u64) -> TypeRef; + pub fn LLVMPointerType(ElementType: TypeRef, AddressSpace: c_uint) -> TypeRef; + pub fn LLVMVectorType(ElementType: TypeRef, ElementCount: c_uint) -> TypeRef; + + pub fn LLVMGetElementType(Ty: TypeRef) -> TypeRef; + pub fn LLVMGetVectorSize(VectorTy: TypeRef) -> c_uint; + + // Operations on other types + pub fn LLVMVoidTypeInContext(C: ContextRef) -> TypeRef; + pub fn LLVMX86MMXTypeInContext(C: ContextRef) -> TypeRef; + pub fn LLVMRustMetadataTypeInContext(C: ContextRef) -> TypeRef; + + // Operations on all values + pub fn LLVMTypeOf(Val: ValueRef) -> TypeRef; + pub fn LLVMGetValueName(Val: ValueRef) -> *const c_char; + pub fn LLVMSetValueName(Val: ValueRef, Name: *const c_char); + pub fn LLVMReplaceAllUsesWith(OldVal: ValueRef, NewVal: ValueRef); + pub fn LLVMSetMetadata(Val: ValueRef, KindID: c_uint, Node: ValueRef); + + // Operations on Uses + pub fn LLVMGetFirstUse(Val: ValueRef) -> UseRef; + pub fn LLVMGetNextUse(U: UseRef) -> UseRef; + pub fn LLVMGetUser(U: UseRef) -> ValueRef; + + // Operations on Users + pub fn LLVMGetOperand(Val: ValueRef, Index: c_uint) -> ValueRef; + + // Operations on constants of any type + pub fn LLVMConstNull(Ty: TypeRef) -> ValueRef; + pub fn LLVMConstICmp(Pred: IntPredicate, V1: ValueRef, V2: ValueRef) -> ValueRef; + pub fn LLVMConstFCmp(Pred: RealPredicate, V1: ValueRef, V2: ValueRef) -> ValueRef; + pub fn LLVMGetUndef(Ty: TypeRef) -> ValueRef; + + // Operations on metadata + pub fn LLVMMDStringInContext(C: ContextRef, Str: *const c_char, SLen: c_uint) -> ValueRef; + pub fn LLVMMDNodeInContext(C: ContextRef, Vals: *const ValueRef, Count: c_uint) -> ValueRef; + pub fn LLVMAddNamedMetadataOperand(M: ModuleRef, Name: *const c_char, Val: ValueRef); + + // Operations on scalar constants + pub fn LLVMConstInt(IntTy: TypeRef, N: c_ulonglong, SignExtend: Bool) -> ValueRef; + pub fn LLVMConstIntOfArbitraryPrecision(IntTy: TypeRef, Wn: c_uint, Ws: *const u64) -> ValueRef; + pub fn LLVMConstIntGetZExtValue(ConstantVal: ValueRef) -> c_ulonglong; + pub fn LLVMConstIntGetSExtValue(ConstantVal: ValueRef) -> c_longlong; + pub fn LLVMRustConstInt128Get(ConstantVal: ValueRef, SExt: bool, + high: *mut u64, low: *mut u64) -> bool; + pub fn LLVMConstRealGetDouble (ConstantVal: ValueRef, losesInfo: *mut Bool) -> f64; + + + // Operations on composite constants + pub fn LLVMConstStringInContext(C: ContextRef, + Str: *const c_char, + Length: c_uint, + DontNullTerminate: Bool) + -> ValueRef; + pub fn LLVMConstStructInContext(C: ContextRef, + ConstantVals: *const ValueRef, + Count: c_uint, + Packed: Bool) + -> ValueRef; + + pub fn LLVMConstArray(ElementTy: TypeRef, + ConstantVals: *const ValueRef, + Length: c_uint) + -> ValueRef; + pub fn LLVMConstVector(ScalarConstantVals: *const ValueRef, Size: c_uint) -> ValueRef; + + // Constant expressions + pub fn LLVMSizeOf(Ty: TypeRef) -> ValueRef; + pub fn LLVMConstNeg(ConstantVal: ValueRef) -> ValueRef; + pub fn LLVMConstFNeg(ConstantVal: ValueRef) -> ValueRef; + pub fn LLVMConstNot(ConstantVal: ValueRef) -> ValueRef; + pub fn LLVMConstAdd(LHSConstant: ValueRef, RHSConstant: ValueRef) -> ValueRef; + pub fn LLVMConstFAdd(LHSConstant: ValueRef, RHSConstant: ValueRef) -> ValueRef; + pub fn LLVMConstSub(LHSConstant: ValueRef, RHSConstant: ValueRef) -> ValueRef; + pub fn LLVMConstFSub(LHSConstant: ValueRef, RHSConstant: ValueRef) -> ValueRef; + pub fn LLVMConstMul(LHSConstant: ValueRef, RHSConstant: ValueRef) -> ValueRef; + pub fn LLVMConstFMul(LHSConstant: ValueRef, RHSConstant: ValueRef) -> ValueRef; + pub fn LLVMConstUDiv(LHSConstant: ValueRef, RHSConstant: ValueRef) -> ValueRef; + pub fn LLVMConstSDiv(LHSConstant: ValueRef, RHSConstant: ValueRef) -> ValueRef; + pub fn LLVMConstFDiv(LHSConstant: ValueRef, RHSConstant: ValueRef) -> ValueRef; + pub fn LLVMConstURem(LHSConstant: ValueRef, RHSConstant: ValueRef) -> ValueRef; + pub fn LLVMConstSRem(LHSConstant: ValueRef, RHSConstant: ValueRef) -> ValueRef; + pub fn LLVMConstFRem(LHSConstant: ValueRef, RHSConstant: ValueRef) -> ValueRef; + pub fn LLVMConstAnd(LHSConstant: ValueRef, RHSConstant: ValueRef) -> ValueRef; + pub fn LLVMConstOr(LHSConstant: ValueRef, RHSConstant: ValueRef) -> ValueRef; + pub fn LLVMConstXor(LHSConstant: ValueRef, RHSConstant: ValueRef) -> ValueRef; + pub fn LLVMConstShl(LHSConstant: ValueRef, RHSConstant: ValueRef) -> ValueRef; + pub fn LLVMConstLShr(LHSConstant: ValueRef, RHSConstant: ValueRef) -> ValueRef; + pub fn LLVMConstAShr(LHSConstant: ValueRef, RHSConstant: ValueRef) -> ValueRef; + pub fn LLVMConstGEP( + ConstantVal: ValueRef, + ConstantIndices: *const ValueRef, + NumIndices: c_uint, + ) -> ValueRef; + pub fn LLVMConstInBoundsGEP( + ConstantVal: ValueRef, + ConstantIndices: *const ValueRef, + NumIndices: c_uint, + ) -> ValueRef; + pub fn LLVMConstTrunc(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef; + pub fn LLVMConstZExt(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef; + pub fn LLVMConstUIToFP(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef; + pub fn LLVMConstSIToFP(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef; + pub fn LLVMConstFPToUI(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef; + pub fn LLVMConstFPToSI(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef; + pub fn LLVMConstPtrToInt(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef; + pub fn LLVMConstIntToPtr(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef; + pub fn LLVMConstBitCast(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef; + pub fn LLVMConstPointerCast(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef; + pub fn LLVMConstIntCast(ConstantVal: ValueRef, ToType: TypeRef, isSigned: Bool) -> ValueRef; + pub fn LLVMConstFPCast(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef; + pub fn LLVMConstExtractValue(AggConstant: ValueRef, + IdxList: *const c_uint, + NumIdx: c_uint) + -> ValueRef; + pub fn LLVMConstInlineAsm(Ty: TypeRef, + AsmString: *const c_char, + Constraints: *const c_char, + HasSideEffects: Bool, + IsAlignStack: Bool) + -> ValueRef; + + + // Operations on global variables, functions, and aliases (globals) + pub fn LLVMGetGlobalParent(Global: ValueRef) -> ModuleRef; + pub fn LLVMIsDeclaration(Global: ValueRef) -> Bool; + pub fn LLVMRustGetLinkage(Global: ValueRef) -> Linkage; + pub fn LLVMRustSetLinkage(Global: ValueRef, RustLinkage: Linkage); + pub fn LLVMGetSection(Global: ValueRef) -> *const c_char; + pub fn LLVMSetSection(Global: ValueRef, Section: *const c_char); + pub fn LLVMRustGetVisibility(Global: ValueRef) -> Visibility; + pub fn LLVMRustSetVisibility(Global: ValueRef, Viz: Visibility); + 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 + pub fn LLVMIsAGlobalVariable(GlobalVar: ValueRef) -> ValueRef; + pub fn LLVMAddGlobal(M: ModuleRef, Ty: TypeRef, Name: *const c_char) -> ValueRef; + pub fn LLVMGetNamedGlobal(M: ModuleRef, Name: *const c_char) -> ValueRef; + pub fn LLVMRustGetOrInsertGlobal(M: ModuleRef, Name: *const c_char, T: TypeRef) -> ValueRef; + pub fn LLVMGetFirstGlobal(M: ModuleRef) -> ValueRef; + pub fn LLVMGetNextGlobal(GlobalVar: ValueRef) -> ValueRef; + pub fn LLVMDeleteGlobal(GlobalVar: ValueRef); + pub fn LLVMGetInitializer(GlobalVar: ValueRef) -> ValueRef; + pub fn LLVMSetInitializer(GlobalVar: ValueRef, ConstantVal: ValueRef); + pub fn LLVMSetThreadLocal(GlobalVar: ValueRef, IsThreadLocal: Bool); + pub fn LLVMSetThreadLocalMode(GlobalVar: ValueRef, Mode: ThreadLocalMode); + pub fn LLVMIsGlobalConstant(GlobalVar: ValueRef) -> Bool; + pub fn LLVMSetGlobalConstant(GlobalVar: ValueRef, IsConstant: Bool); + pub fn LLVMRustGetNamedValue(M: ModuleRef, Name: *const c_char) -> ValueRef; + pub fn LLVMSetTailCall(CallInst: ValueRef, IsTailCall: Bool); + + // Operations on functions + pub fn LLVMAddFunction(M: ModuleRef, Name: *const c_char, FunctionTy: TypeRef) -> ValueRef; + pub fn LLVMGetNamedFunction(M: ModuleRef, Name: *const c_char) -> ValueRef; + pub fn LLVMGetFirstFunction(M: ModuleRef) -> ValueRef; + pub fn LLVMGetNextFunction(Fn: ValueRef) -> ValueRef; + pub fn LLVMRustGetOrInsertFunction(M: ModuleRef, + Name: *const c_char, + FunctionTy: TypeRef) + -> ValueRef; + pub fn LLVMSetFunctionCallConv(Fn: ValueRef, CC: c_uint); + pub fn LLVMRustAddAlignmentAttr(Fn: ValueRef, index: c_uint, bytes: u32); + pub fn LLVMRustAddDereferenceableAttr(Fn: ValueRef, index: c_uint, bytes: u64); + pub fn LLVMRustAddDereferenceableOrNullAttr(Fn: ValueRef, index: c_uint, bytes: u64); + pub fn LLVMRustAddFunctionAttribute(Fn: ValueRef, index: c_uint, attr: Attribute); + pub fn LLVMRustAddFunctionAttrStringValue(Fn: ValueRef, + index: c_uint, + Name: *const c_char, + Value: *const c_char); + pub fn LLVMRustRemoveFunctionAttributes(Fn: ValueRef, index: c_uint, attr: Attribute); + + // Operations on parameters + pub fn LLVMCountParams(Fn: ValueRef) -> c_uint; + pub fn LLVMGetParam(Fn: ValueRef, Index: c_uint) -> ValueRef; + + // Operations on basic blocks + pub fn LLVMBasicBlockAsValue(BB: BasicBlockRef) -> ValueRef; + pub fn LLVMGetBasicBlockParent(BB: BasicBlockRef) -> ValueRef; + pub fn LLVMAppendBasicBlockInContext(C: ContextRef, + Fn: ValueRef, + Name: *const c_char) + -> BasicBlockRef; + pub fn LLVMDeleteBasicBlock(BB: BasicBlockRef); + + // Operations on instructions + pub fn LLVMGetInstructionParent(Inst: ValueRef) -> BasicBlockRef; + pub fn LLVMGetFirstBasicBlock(Fn: ValueRef) -> BasicBlockRef; + pub fn LLVMGetFirstInstruction(BB: BasicBlockRef) -> ValueRef; + pub fn LLVMInstructionEraseFromParent(Inst: ValueRef); + + // Operations on call sites + pub fn LLVMSetInstructionCallConv(Instr: ValueRef, CC: c_uint); + pub fn LLVMRustAddCallSiteAttribute(Instr: ValueRef, index: c_uint, attr: Attribute); + pub fn LLVMRustAddAlignmentCallSiteAttr(Instr: ValueRef, index: c_uint, bytes: u32); + pub fn LLVMRustAddDereferenceableCallSiteAttr(Instr: ValueRef, index: c_uint, bytes: u64); + pub fn LLVMRustAddDereferenceableOrNullCallSiteAttr(Instr: ValueRef, + index: c_uint, + bytes: u64); + + // Operations on load/store instructions (only) + pub fn LLVMSetVolatile(MemoryAccessInst: ValueRef, volatile: Bool); + + // Operations on phi nodes + pub fn LLVMAddIncoming(PhiNode: ValueRef, + IncomingValues: *const ValueRef, + IncomingBlocks: *const BasicBlockRef, + Count: c_uint); + + // Instruction builders + pub fn LLVMCreateBuilderInContext(C: ContextRef) -> BuilderRef; + pub fn LLVMPositionBuilder(Builder: BuilderRef, Block: BasicBlockRef, Instr: ValueRef); + pub fn LLVMPositionBuilderBefore(Builder: BuilderRef, Instr: ValueRef); + pub fn LLVMPositionBuilderAtEnd(Builder: BuilderRef, Block: BasicBlockRef); + pub fn LLVMGetInsertBlock(Builder: BuilderRef) -> BasicBlockRef; + pub fn LLVMDisposeBuilder(Builder: BuilderRef); + + // Metadata + pub fn LLVMSetCurrentDebugLocation(Builder: BuilderRef, L: ValueRef); + pub fn LLVMGetCurrentDebugLocation(Builder: BuilderRef) -> ValueRef; + pub fn LLVMSetInstDebugLocation(Builder: BuilderRef, Inst: ValueRef); + + // Terminators + pub fn LLVMBuildRetVoid(B: BuilderRef) -> ValueRef; + pub fn LLVMBuildRet(B: BuilderRef, V: ValueRef) -> ValueRef; + pub fn LLVMBuildAggregateRet(B: BuilderRef, RetVals: *const ValueRef, N: c_uint) -> ValueRef; + pub fn LLVMBuildBr(B: BuilderRef, Dest: BasicBlockRef) -> ValueRef; + pub fn LLVMBuildCondBr(B: BuilderRef, + If: ValueRef, + Then: BasicBlockRef, + Else: BasicBlockRef) + -> ValueRef; + pub fn LLVMBuildSwitch(B: BuilderRef, + V: ValueRef, + Else: BasicBlockRef, + NumCases: c_uint) + -> ValueRef; + pub fn LLVMBuildIndirectBr(B: BuilderRef, Addr: ValueRef, NumDests: c_uint) -> ValueRef; + pub fn LLVMRustBuildInvoke(B: BuilderRef, + Fn: ValueRef, + Args: *const ValueRef, + NumArgs: c_uint, + Then: BasicBlockRef, + Catch: BasicBlockRef, + Bundle: OperandBundleDefRef, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildLandingPad(B: BuilderRef, + Ty: TypeRef, + PersFn: ValueRef, + NumClauses: c_uint, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildResume(B: BuilderRef, Exn: ValueRef) -> ValueRef; + pub fn LLVMBuildUnreachable(B: BuilderRef) -> ValueRef; + + pub fn LLVMRustBuildCleanupPad(B: BuilderRef, + ParentPad: ValueRef, + ArgCnt: c_uint, + Args: *const ValueRef, + Name: *const c_char) + -> ValueRef; + pub fn LLVMRustBuildCleanupRet(B: BuilderRef, + CleanupPad: ValueRef, + UnwindBB: BasicBlockRef) + -> ValueRef; + pub fn LLVMRustBuildCatchPad(B: BuilderRef, + ParentPad: ValueRef, + ArgCnt: c_uint, + Args: *const ValueRef, + Name: *const c_char) + -> ValueRef; + pub fn LLVMRustBuildCatchRet(B: BuilderRef, Pad: ValueRef, BB: BasicBlockRef) -> ValueRef; + pub fn LLVMRustBuildCatchSwitch(Builder: BuilderRef, + ParentPad: ValueRef, + BB: BasicBlockRef, + NumHandlers: c_uint, + Name: *const c_char) + -> ValueRef; + pub fn LLVMRustAddHandler(CatchSwitch: ValueRef, Handler: BasicBlockRef); + pub fn LLVMSetPersonalityFn(Func: ValueRef, Pers: ValueRef); + + // Add a case to the switch instruction + pub fn LLVMAddCase(Switch: ValueRef, OnVal: ValueRef, Dest: BasicBlockRef); + + // Add a clause to the landing pad instruction + pub fn LLVMAddClause(LandingPad: ValueRef, ClauseVal: ValueRef); + + // Set the cleanup on a landing pad instruction + pub fn LLVMSetCleanup(LandingPad: ValueRef, Val: Bool); + + // Arithmetic + pub fn LLVMBuildAdd(B: BuilderRef, + LHS: ValueRef, + RHS: ValueRef, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildNSWAdd(B: BuilderRef, + LHS: ValueRef, + RHS: ValueRef, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildNUWAdd(B: BuilderRef, + LHS: ValueRef, + RHS: ValueRef, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildFAdd(B: BuilderRef, + LHS: ValueRef, + RHS: ValueRef, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildSub(B: BuilderRef, + LHS: ValueRef, + RHS: ValueRef, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildNSWSub(B: BuilderRef, + LHS: ValueRef, + RHS: ValueRef, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildNUWSub(B: BuilderRef, + LHS: ValueRef, + RHS: ValueRef, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildFSub(B: BuilderRef, + LHS: ValueRef, + RHS: ValueRef, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildMul(B: BuilderRef, + LHS: ValueRef, + RHS: ValueRef, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildNSWMul(B: BuilderRef, + LHS: ValueRef, + RHS: ValueRef, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildNUWMul(B: BuilderRef, + LHS: ValueRef, + RHS: ValueRef, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildFMul(B: BuilderRef, + LHS: ValueRef, + RHS: ValueRef, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildUDiv(B: BuilderRef, + LHS: ValueRef, + RHS: ValueRef, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildExactUDiv(B: BuilderRef, + LHS: ValueRef, + RHS: ValueRef, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildSDiv(B: BuilderRef, + LHS: ValueRef, + RHS: ValueRef, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildExactSDiv(B: BuilderRef, + LHS: ValueRef, + RHS: ValueRef, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildFDiv(B: BuilderRef, + LHS: ValueRef, + RHS: ValueRef, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildURem(B: BuilderRef, + LHS: ValueRef, + RHS: ValueRef, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildSRem(B: BuilderRef, + LHS: ValueRef, + RHS: ValueRef, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildFRem(B: BuilderRef, + LHS: ValueRef, + RHS: ValueRef, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildShl(B: BuilderRef, + LHS: ValueRef, + RHS: ValueRef, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildLShr(B: BuilderRef, + LHS: ValueRef, + RHS: ValueRef, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildAShr(B: BuilderRef, + LHS: ValueRef, + RHS: ValueRef, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildAnd(B: BuilderRef, + LHS: ValueRef, + RHS: ValueRef, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildOr(B: BuilderRef, + LHS: ValueRef, + RHS: ValueRef, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildXor(B: BuilderRef, + LHS: ValueRef, + RHS: ValueRef, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildBinOp(B: BuilderRef, + Op: Opcode, + LHS: ValueRef, + RHS: ValueRef, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildNeg(B: BuilderRef, V: ValueRef, Name: *const c_char) -> ValueRef; + pub fn LLVMBuildNSWNeg(B: BuilderRef, V: ValueRef, Name: *const c_char) -> ValueRef; + pub fn LLVMBuildNUWNeg(B: BuilderRef, V: ValueRef, Name: *const c_char) -> ValueRef; + pub fn LLVMBuildFNeg(B: BuilderRef, V: ValueRef, Name: *const c_char) -> ValueRef; + pub fn LLVMBuildNot(B: BuilderRef, V: ValueRef, Name: *const c_char) -> ValueRef; + pub fn LLVMRustSetHasUnsafeAlgebra(Instr: ValueRef); + + // Memory + pub fn LLVMBuildAlloca(B: BuilderRef, Ty: TypeRef, Name: *const c_char) -> ValueRef; + pub fn LLVMBuildFree(B: BuilderRef, PointerVal: ValueRef) -> ValueRef; + pub fn LLVMBuildLoad(B: BuilderRef, PointerVal: ValueRef, Name: *const c_char) -> ValueRef; + + pub fn LLVMBuildStore(B: BuilderRef, Val: ValueRef, Ptr: ValueRef) -> ValueRef; + + pub fn LLVMBuildGEP(B: BuilderRef, + Pointer: ValueRef, + Indices: *const ValueRef, + NumIndices: c_uint, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildInBoundsGEP(B: BuilderRef, + Pointer: ValueRef, + Indices: *const ValueRef, + NumIndices: c_uint, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildStructGEP(B: BuilderRef, + Pointer: ValueRef, + Idx: c_uint, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildGlobalString(B: BuilderRef, + Str: *const c_char, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildGlobalStringPtr(B: BuilderRef, + Str: *const c_char, + Name: *const c_char) + -> ValueRef; + + // Casts + pub fn LLVMBuildTrunc(B: BuilderRef, + Val: ValueRef, + DestTy: TypeRef, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildZExt(B: BuilderRef, + Val: ValueRef, + DestTy: TypeRef, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildSExt(B: BuilderRef, + Val: ValueRef, + DestTy: TypeRef, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildFPToUI(B: BuilderRef, + Val: ValueRef, + DestTy: TypeRef, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildFPToSI(B: BuilderRef, + Val: ValueRef, + DestTy: TypeRef, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildUIToFP(B: BuilderRef, + Val: ValueRef, + DestTy: TypeRef, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildSIToFP(B: BuilderRef, + Val: ValueRef, + DestTy: TypeRef, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildFPTrunc(B: BuilderRef, + Val: ValueRef, + DestTy: TypeRef, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildFPExt(B: BuilderRef, + Val: ValueRef, + DestTy: TypeRef, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildPtrToInt(B: BuilderRef, + Val: ValueRef, + DestTy: TypeRef, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildIntToPtr(B: BuilderRef, + Val: ValueRef, + DestTy: TypeRef, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildBitCast(B: BuilderRef, + Val: ValueRef, + DestTy: TypeRef, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildZExtOrBitCast(B: BuilderRef, + Val: ValueRef, + DestTy: TypeRef, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildSExtOrBitCast(B: BuilderRef, + Val: ValueRef, + DestTy: TypeRef, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildTruncOrBitCast(B: BuilderRef, + Val: ValueRef, + DestTy: TypeRef, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildCast(B: BuilderRef, + Op: Opcode, + Val: ValueRef, + DestTy: TypeRef, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildPointerCast(B: BuilderRef, + Val: ValueRef, + DestTy: TypeRef, + Name: *const c_char) + -> ValueRef; + pub fn LLVMRustBuildIntCast(B: BuilderRef, + Val: ValueRef, + DestTy: TypeRef, + IsSized: bool) + -> ValueRef; + pub fn LLVMBuildFPCast(B: BuilderRef, + Val: ValueRef, + DestTy: TypeRef, + Name: *const c_char) + -> ValueRef; + + // Comparisons + pub fn LLVMBuildICmp(B: BuilderRef, + Op: c_uint, + LHS: ValueRef, + RHS: ValueRef, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildFCmp(B: BuilderRef, + Op: c_uint, + LHS: ValueRef, + RHS: ValueRef, + Name: *const c_char) + -> ValueRef; + + // Miscellaneous instructions + pub fn LLVMBuildPhi(B: BuilderRef, Ty: TypeRef, Name: *const c_char) -> ValueRef; + pub fn LLVMRustBuildCall(B: BuilderRef, + Fn: ValueRef, + Args: *const ValueRef, + NumArgs: c_uint, + Bundle: OperandBundleDefRef, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildSelect(B: BuilderRef, + If: ValueRef, + Then: ValueRef, + Else: ValueRef, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildVAArg(B: BuilderRef, + list: ValueRef, + Ty: TypeRef, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildExtractElement(B: BuilderRef, + VecVal: ValueRef, + Index: ValueRef, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildInsertElement(B: BuilderRef, + VecVal: ValueRef, + EltVal: ValueRef, + Index: ValueRef, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildShuffleVector(B: BuilderRef, + V1: ValueRef, + V2: ValueRef, + Mask: ValueRef, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildExtractValue(B: BuilderRef, + AggVal: ValueRef, + Index: c_uint, + Name: *const c_char) + -> ValueRef; + pub fn LLVMBuildInsertValue(B: BuilderRef, + AggVal: ValueRef, + EltVal: ValueRef, + Index: c_uint, + Name: *const c_char) + -> ValueRef; + + pub fn LLVMRustBuildVectorReduceFAdd(B: BuilderRef, + Acc: ValueRef, + Src: ValueRef) + -> ValueRef; + pub fn LLVMRustBuildVectorReduceFMul(B: BuilderRef, + Acc: ValueRef, + Src: ValueRef) + -> ValueRef; + pub fn LLVMRustBuildVectorReduceAdd(B: BuilderRef, + Src: ValueRef) + -> ValueRef; + pub fn LLVMRustBuildVectorReduceMul(B: BuilderRef, + Src: ValueRef) + -> ValueRef; + pub fn LLVMRustBuildVectorReduceAnd(B: BuilderRef, + Src: ValueRef) + -> ValueRef; + pub fn LLVMRustBuildVectorReduceOr(B: BuilderRef, + Src: ValueRef) + -> ValueRef; + pub fn LLVMRustBuildVectorReduceXor(B: BuilderRef, + Src: ValueRef) + -> ValueRef; + pub fn LLVMRustBuildVectorReduceMin(B: BuilderRef, + Src: ValueRef, + IsSigned: bool) + -> ValueRef; + pub fn LLVMRustBuildVectorReduceMax(B: BuilderRef, + Src: ValueRef, + IsSigned: bool) + -> ValueRef; + pub fn LLVMRustBuildVectorReduceFMin(B: BuilderRef, + Src: ValueRef, + IsNaN: bool) + -> ValueRef; + pub fn LLVMRustBuildVectorReduceFMax(B: BuilderRef, + Src: ValueRef, + IsNaN: bool) + -> ValueRef; + + pub fn LLVMRustBuildMinNum(B: BuilderRef, LHS: ValueRef, LHS: ValueRef) -> ValueRef; + pub fn LLVMRustBuildMaxNum(B: BuilderRef, LHS: ValueRef, LHS: ValueRef) -> ValueRef; + + pub fn LLVMBuildIsNull(B: BuilderRef, Val: ValueRef, Name: *const c_char) -> ValueRef; + pub fn LLVMBuildIsNotNull(B: BuilderRef, Val: ValueRef, Name: *const c_char) -> ValueRef; + pub fn LLVMBuildPtrDiff(B: BuilderRef, + LHS: ValueRef, + RHS: ValueRef, + Name: *const c_char) + -> ValueRef; + + // Atomic Operations + pub fn LLVMRustBuildAtomicLoad(B: BuilderRef, + PointerVal: ValueRef, + Name: *const c_char, + Order: AtomicOrdering) + -> ValueRef; + + pub fn LLVMRustBuildAtomicStore(B: BuilderRef, + Val: ValueRef, + Ptr: ValueRef, + Order: AtomicOrdering) + -> ValueRef; + + pub fn LLVMRustBuildAtomicCmpXchg(B: BuilderRef, + LHS: ValueRef, + CMP: ValueRef, + RHS: ValueRef, + Order: AtomicOrdering, + FailureOrder: AtomicOrdering, + Weak: Bool) + -> ValueRef; + + pub fn LLVMBuildAtomicRMW(B: BuilderRef, + Op: AtomicRmwBinOp, + LHS: ValueRef, + RHS: ValueRef, + Order: AtomicOrdering, + SingleThreaded: Bool) + -> ValueRef; + + pub fn LLVMRustBuildAtomicFence(B: BuilderRef, + Order: AtomicOrdering, + Scope: SynchronizationScope); + + + // Selected entries from the downcasts. + pub fn LLVMIsATerminatorInst(Inst: ValueRef) -> ValueRef; + pub fn LLVMIsAStoreInst(Inst: ValueRef) -> ValueRef; + + /// Writes a module to the specified path. Returns 0 on success. + pub fn LLVMWriteBitcodeToFile(M: ModuleRef, Path: *const c_char) -> c_int; + + /// Creates target data from a target layout string. + pub fn LLVMCreateTargetData(StringRep: *const c_char) -> TargetDataRef; + + /// Disposes target data. + pub fn LLVMDisposeTargetData(TD: TargetDataRef); + + /// Creates a pass manager. + pub fn LLVMCreatePassManager() -> PassManagerRef; + + /// Creates a function-by-function pass manager + pub fn LLVMCreateFunctionPassManagerForModule(M: ModuleRef) -> PassManagerRef; + + /// Disposes a pass manager. + pub fn LLVMDisposePassManager(PM: PassManagerRef); + + /// Runs a pass manager on a module. + pub fn LLVMRunPassManager(PM: PassManagerRef, M: ModuleRef) -> Bool; + + pub fn LLVMInitializePasses(); + + pub fn LLVMPassManagerBuilderCreate() -> PassManagerBuilderRef; + pub fn LLVMPassManagerBuilderDispose(PMB: PassManagerBuilderRef); + pub fn LLVMPassManagerBuilderSetSizeLevel(PMB: PassManagerBuilderRef, Value: Bool); + pub fn LLVMPassManagerBuilderSetDisableUnrollLoops(PMB: PassManagerBuilderRef, Value: Bool); + pub fn LLVMPassManagerBuilderUseInlinerWithThreshold(PMB: PassManagerBuilderRef, + threshold: c_uint); + pub fn LLVMPassManagerBuilderPopulateModulePassManager(PMB: PassManagerBuilderRef, + PM: PassManagerRef); + + pub fn LLVMPassManagerBuilderPopulateFunctionPassManager(PMB: PassManagerBuilderRef, + PM: PassManagerRef); + pub fn LLVMPassManagerBuilderPopulateLTOPassManager(PMB: PassManagerBuilderRef, + PM: PassManagerRef, + Internalize: Bool, + RunInliner: Bool); + pub fn LLVMRustPassManagerBuilderPopulateThinLTOPassManager( + PMB: PassManagerBuilderRef, + PM: PassManagerRef) -> bool; + + // Stuff that's in rustllvm/ because it's not upstream yet. + + /// Opens an object file. + pub fn LLVMCreateObjectFile(MemBuf: MemoryBufferRef) -> ObjectFileRef; + /// Closes an object file. + pub fn LLVMDisposeObjectFile(ObjFile: ObjectFileRef); + + /// Enumerates the sections in an object file. + pub fn LLVMGetSections(ObjFile: ObjectFileRef) -> SectionIteratorRef; + /// Destroys a section iterator. + pub fn LLVMDisposeSectionIterator(SI: SectionIteratorRef); + /// Returns true if the section iterator is at the end of the section + /// list: + pub fn LLVMIsSectionIteratorAtEnd(ObjFile: ObjectFileRef, SI: SectionIteratorRef) -> Bool; + /// Moves the section iterator to point to the next section. + pub fn LLVMMoveToNextSection(SI: SectionIteratorRef); + /// Returns the current section size. + pub fn LLVMGetSectionSize(SI: SectionIteratorRef) -> c_ulonglong; + /// Returns the current section contents as a string buffer. + pub fn LLVMGetSectionContents(SI: SectionIteratorRef) -> *const c_char; + + /// Reads the given file and returns it as a memory buffer. Use + /// LLVMDisposeMemoryBuffer() to get rid of it. + pub fn LLVMRustCreateMemoryBufferWithContentsOfFile(Path: *const c_char) -> MemoryBufferRef; + + pub fn LLVMStartMultithreaded() -> Bool; + + /// Returns a string describing the last error caused by an LLVMRust* call. + pub fn LLVMRustGetLastError() -> *const c_char; + + /// Print the pass timings since static dtors aren't picking them up. + pub fn LLVMRustPrintPassTimings(); + + pub fn LLVMStructCreateNamed(C: ContextRef, Name: *const c_char) -> TypeRef; + + pub fn LLVMStructSetBody(StructTy: TypeRef, + ElementTypes: *const TypeRef, + ElementCount: c_uint, + Packed: Bool); + + /// Prepares inline assembly. + pub fn LLVMRustInlineAsm(Ty: TypeRef, + AsmString: *const c_char, + Constraints: *const c_char, + SideEffects: Bool, + AlignStack: Bool, + Dialect: AsmDialect) + -> ValueRef; + + pub fn LLVMRustDebugMetadataVersion() -> u32; + pub fn LLVMRustVersionMajor() -> u32; + pub fn LLVMRustVersionMinor() -> u32; + + pub fn LLVMRustAddModuleFlag(M: ModuleRef, name: *const c_char, value: u32); + + pub fn LLVMRustMetadataAsValue(C: ContextRef, MD: MetadataRef) -> ValueRef; + + pub fn LLVMRustDIBuilderCreate(M: ModuleRef) -> DIBuilderRef; + + pub fn LLVMRustDIBuilderDispose(Builder: DIBuilderRef); + + pub fn LLVMRustDIBuilderFinalize(Builder: DIBuilderRef); + + pub fn LLVMRustDIBuilderCreateCompileUnit(Builder: DIBuilderRef, + Lang: c_uint, + File: DIFile, + Producer: *const c_char, + isOptimized: bool, + Flags: *const c_char, + RuntimeVer: c_uint, + SplitName: *const c_char) + -> DIDescriptor; + + pub fn LLVMRustDIBuilderCreateFile(Builder: DIBuilderRef, + Filename: *const c_char, + Directory: *const c_char) + -> DIFile; + + pub fn LLVMRustDIBuilderCreateSubroutineType(Builder: DIBuilderRef, + File: DIFile, + ParameterTypes: DIArray) + -> DICompositeType; + + pub fn LLVMRustDIBuilderCreateFunction(Builder: DIBuilderRef, + Scope: DIDescriptor, + Name: *const c_char, + LinkageName: *const c_char, + File: DIFile, + LineNo: c_uint, + Ty: DIType, + isLocalToUnit: bool, + isDefinition: bool, + ScopeLine: c_uint, + Flags: DIFlags, + isOptimized: bool, + Fn: ValueRef, + TParam: DIArray, + Decl: DIDescriptor) + -> DISubprogram; + + pub fn LLVMRustDIBuilderCreateBasicType(Builder: DIBuilderRef, + Name: *const c_char, + SizeInBits: u64, + AlignInBits: u32, + Encoding: c_uint) + -> DIBasicType; + + pub fn LLVMRustDIBuilderCreatePointerType(Builder: DIBuilderRef, + PointeeTy: DIType, + SizeInBits: u64, + AlignInBits: u32, + Name: *const c_char) + -> DIDerivedType; + + pub fn LLVMRustDIBuilderCreateStructType(Builder: DIBuilderRef, + Scope: DIDescriptor, + Name: *const c_char, + File: DIFile, + LineNumber: c_uint, + SizeInBits: u64, + AlignInBits: u32, + Flags: DIFlags, + DerivedFrom: DIType, + Elements: DIArray, + RunTimeLang: c_uint, + VTableHolder: DIType, + UniqueId: *const c_char) + -> DICompositeType; + + pub fn LLVMRustDIBuilderCreateMemberType(Builder: DIBuilderRef, + Scope: DIDescriptor, + Name: *const c_char, + File: DIFile, + LineNo: c_uint, + SizeInBits: u64, + AlignInBits: u32, + OffsetInBits: u64, + Flags: DIFlags, + Ty: DIType) + -> DIDerivedType; + + pub fn LLVMRustDIBuilderCreateLexicalBlock(Builder: DIBuilderRef, + Scope: DIScope, + File: DIFile, + Line: c_uint, + Col: c_uint) + -> DILexicalBlock; + + pub fn LLVMRustDIBuilderCreateLexicalBlockFile(Builder: DIBuilderRef, + Scope: DIScope, + File: DIFile) + -> DILexicalBlock; + + pub fn LLVMRustDIBuilderCreateStaticVariable(Builder: DIBuilderRef, + Context: DIScope, + Name: *const c_char, + LinkageName: *const c_char, + File: DIFile, + LineNo: c_uint, + Ty: DIType, + isLocalToUnit: bool, + Val: ValueRef, + Decl: DIDescriptor, + AlignInBits: u32) + -> DIGlobalVariable; + + pub fn LLVMRustDIBuilderCreateVariable(Builder: DIBuilderRef, + Tag: c_uint, + Scope: DIDescriptor, + Name: *const c_char, + File: DIFile, + LineNo: c_uint, + Ty: DIType, + AlwaysPreserve: bool, + Flags: DIFlags, + ArgNo: c_uint, + AlignInBits: u32) + -> DIVariable; + + pub fn LLVMRustDIBuilderCreateArrayType(Builder: DIBuilderRef, + Size: u64, + AlignInBits: u32, + Ty: DIType, + Subscripts: DIArray) + -> DIType; + + pub fn LLVMRustDIBuilderCreateVectorType(Builder: DIBuilderRef, + Size: u64, + AlignInBits: u32, + Ty: DIType, + Subscripts: DIArray) + -> DIType; + + pub fn LLVMRustDIBuilderGetOrCreateSubrange(Builder: DIBuilderRef, + Lo: i64, + Count: i64) + -> DISubrange; + + pub fn LLVMRustDIBuilderGetOrCreateArray(Builder: DIBuilderRef, + Ptr: *const DIDescriptor, + Count: c_uint) + -> DIArray; + + pub fn LLVMRustDIBuilderInsertDeclareAtEnd(Builder: DIBuilderRef, + Val: ValueRef, + VarInfo: DIVariable, + AddrOps: *const i64, + AddrOpsCount: c_uint, + DL: ValueRef, + InsertAtEnd: BasicBlockRef) + -> ValueRef; + + pub fn LLVMRustDIBuilderCreateEnumerator(Builder: DIBuilderRef, + Name: *const c_char, + Val: u64) + -> DIEnumerator; + + pub fn LLVMRustDIBuilderCreateEnumerationType(Builder: DIBuilderRef, + Scope: DIScope, + Name: *const c_char, + File: DIFile, + LineNumber: c_uint, + SizeInBits: u64, + AlignInBits: u32, + Elements: DIArray, + ClassType: DIType) + -> DIType; + + pub fn LLVMRustDIBuilderCreateUnionType(Builder: DIBuilderRef, + Scope: DIScope, + Name: *const c_char, + File: DIFile, + LineNumber: c_uint, + SizeInBits: u64, + AlignInBits: u32, + Flags: DIFlags, + Elements: DIArray, + RunTimeLang: c_uint, + UniqueId: *const c_char) + -> DIType; + + pub fn LLVMSetUnnamedAddr(GlobalVar: ValueRef, UnnamedAddr: Bool); + + pub fn LLVMRustDIBuilderCreateTemplateTypeParameter(Builder: DIBuilderRef, + Scope: DIScope, + Name: *const c_char, + Ty: DIType, + File: DIFile, + LineNo: c_uint, + ColumnNo: c_uint) + -> DITemplateTypeParameter; + + + pub fn LLVMRustDIBuilderCreateNameSpace(Builder: DIBuilderRef, + Scope: DIScope, + Name: *const c_char, + File: DIFile, + LineNo: c_uint) + -> DINameSpace; + pub fn LLVMRustDICompositeTypeSetTypeArray(Builder: DIBuilderRef, + CompositeType: DIType, + TypeArray: DIArray); + + + pub fn LLVMRustDIBuilderCreateDebugLocation(Context: ContextRef, + Line: c_uint, + Column: c_uint, + Scope: DIScope, + InlinedAt: MetadataRef) + -> ValueRef; + pub fn LLVMRustDIBuilderCreateOpDeref() -> i64; + pub fn LLVMRustDIBuilderCreateOpPlusUconst() -> i64; + + pub fn LLVMRustWriteTypeToString(Type: TypeRef, s: RustStringRef); + pub fn LLVMRustWriteValueToString(value_ref: ValueRef, s: RustStringRef); + + pub fn LLVMIsAConstantInt(value_ref: ValueRef) -> ValueRef; + pub fn LLVMIsAConstantFP(value_ref: ValueRef) -> ValueRef; + + pub fn LLVMRustPassKind(Pass: PassRef) -> PassKind; + pub fn LLVMRustFindAndCreatePass(Pass: *const c_char) -> PassRef; + pub fn LLVMRustAddPass(PM: PassManagerRef, Pass: PassRef); + + pub fn LLVMRustHasFeature(T: TargetMachineRef, s: *const c_char) -> bool; + + pub fn LLVMRustPrintTargetCPUs(T: TargetMachineRef); + pub fn LLVMRustPrintTargetFeatures(T: TargetMachineRef); + + pub fn LLVMRustCreateTargetMachine(Triple: *const c_char, + CPU: *const c_char, + Features: *const c_char, + Model: CodeModel, + Reloc: RelocMode, + Level: CodeGenOptLevel, + UseSoftFP: bool, + PositionIndependentExecutable: bool, + FunctionSections: bool, + DataSections: bool, + TrapUnreachable: bool, + Singlethread: bool) + -> TargetMachineRef; + pub fn LLVMRustDisposeTargetMachine(T: TargetMachineRef); + pub fn LLVMRustAddAnalysisPasses(T: TargetMachineRef, PM: PassManagerRef, M: ModuleRef); + pub fn LLVMRustAddBuilderLibraryInfo(PMB: PassManagerBuilderRef, + M: ModuleRef, + DisableSimplifyLibCalls: bool); + pub fn LLVMRustConfigurePassManagerBuilder(PMB: PassManagerBuilderRef, + OptLevel: CodeGenOptLevel, + MergeFunctions: bool, + SLPVectorize: bool, + LoopVectorize: bool, + PrepareForThinLTO: bool, + PGOGenPath: *const c_char, + PGOUsePath: *const c_char); + pub fn LLVMRustAddLibraryInfo(PM: PassManagerRef, + M: ModuleRef, + DisableSimplifyLibCalls: bool); + pub fn LLVMRustRunFunctionPassManager(PM: PassManagerRef, M: ModuleRef); + pub fn LLVMRustWriteOutputFile(T: TargetMachineRef, + PM: PassManagerRef, + M: ModuleRef, + Output: *const c_char, + FileType: FileType) + -> LLVMRustResult; + pub fn LLVMRustPrintModule(PM: PassManagerRef, + M: ModuleRef, + Output: *const c_char, + Demangle: extern fn(*const c_char, + size_t, + *mut c_char, + size_t) -> size_t); + pub fn LLVMRustSetLLVMOptions(Argc: c_int, Argv: *const *const c_char); + pub fn LLVMRustPrintPasses(); + pub fn LLVMRustSetNormalizedTarget(M: ModuleRef, triple: *const c_char); + pub fn LLVMRustAddAlwaysInlinePass(P: PassManagerBuilderRef, AddLifetimes: bool); + pub fn LLVMRustRunRestrictionPass(M: ModuleRef, syms: *const *const c_char, len: size_t); + pub fn LLVMRustMarkAllFunctionsNounwind(M: ModuleRef); + + pub fn LLVMRustOpenArchive(path: *const c_char) -> ArchiveRef; + pub fn LLVMRustArchiveIteratorNew(AR: ArchiveRef) -> ArchiveIteratorRef; + pub fn LLVMRustArchiveIteratorNext(AIR: ArchiveIteratorRef) -> ArchiveChildRef; + pub fn LLVMRustArchiveChildName(ACR: ArchiveChildRef, size: *mut size_t) -> *const c_char; + pub fn LLVMRustArchiveChildData(ACR: ArchiveChildRef, size: *mut size_t) -> *const c_char; + pub fn LLVMRustArchiveChildFree(ACR: ArchiveChildRef); + pub fn LLVMRustArchiveIteratorFree(AIR: ArchiveIteratorRef); + pub fn LLVMRustDestroyArchive(AR: ArchiveRef); + + pub fn LLVMRustGetSectionName(SI: SectionIteratorRef, data: *mut *const c_char) -> size_t; + + pub fn LLVMRustWriteTwineToString(T: TwineRef, s: RustStringRef); + + pub fn LLVMContextSetDiagnosticHandler(C: ContextRef, + Handler: DiagnosticHandler, + DiagnosticContext: *mut c_void); + + pub fn LLVMRustUnpackOptimizationDiagnostic(DI: DiagnosticInfoRef, + pass_name_out: RustStringRef, + function_out: *mut ValueRef, + loc_line_out: *mut c_uint, + loc_column_out: *mut c_uint, + loc_filename_out: RustStringRef, + message_out: RustStringRef); + pub fn LLVMRustUnpackInlineAsmDiagnostic(DI: DiagnosticInfoRef, + cookie_out: *mut c_uint, + message_out: *mut TwineRef, + instruction_out: *mut ValueRef); + + pub fn LLVMRustWriteDiagnosticInfoToString(DI: DiagnosticInfoRef, s: RustStringRef); + pub fn LLVMRustGetDiagInfoKind(DI: DiagnosticInfoRef) -> DiagnosticKind; + + pub fn LLVMRustSetInlineAsmDiagnosticHandler(C: ContextRef, + H: InlineAsmDiagHandler, + CX: *mut c_void); + + pub fn LLVMRustWriteSMDiagnosticToString(d: SMDiagnosticRef, s: RustStringRef); + + pub fn LLVMRustWriteArchive(Dst: *const c_char, + NumMembers: size_t, + Members: *const RustArchiveMemberRef, + WriteSymbtab: bool, + Kind: ArchiveKind) + -> LLVMRustResult; + pub fn LLVMRustArchiveMemberNew(Filename: *const c_char, + Name: *const c_char, + Child: ArchiveChildRef) + -> RustArchiveMemberRef; + pub fn LLVMRustArchiveMemberFree(Member: RustArchiveMemberRef); + + pub fn LLVMRustSetDataLayoutFromTargetMachine(M: ModuleRef, TM: TargetMachineRef); + + pub fn LLVMRustBuildOperandBundleDef(Name: *const c_char, + Inputs: *const ValueRef, + NumInputs: c_uint) + -> OperandBundleDefRef; + pub fn LLVMRustFreeOperandBundleDef(Bundle: OperandBundleDefRef); + + pub fn LLVMRustPositionBuilderAtStart(B: BuilderRef, BB: BasicBlockRef); + + pub fn LLVMRustSetComdat(M: ModuleRef, V: ValueRef, Name: *const c_char); + pub fn LLVMRustUnsetComdat(V: ValueRef); + pub fn LLVMRustSetModulePIELevel(M: ModuleRef); + pub fn LLVMRustModuleBufferCreate(M: ModuleRef) -> *mut ModuleBuffer; + pub fn LLVMRustModuleBufferPtr(p: *const ModuleBuffer) -> *const u8; + pub fn LLVMRustModuleBufferLen(p: *const ModuleBuffer) -> usize; + pub fn LLVMRustModuleBufferFree(p: *mut ModuleBuffer); + pub fn LLVMRustModuleCost(M: ModuleRef) -> u64; + + pub fn LLVMRustThinLTOAvailable() -> bool; + pub fn LLVMRustPGOAvailable() -> bool; + pub fn LLVMRustWriteThinBitcodeToFile(PMR: PassManagerRef, + M: ModuleRef, + BC: *const c_char) -> bool; + pub fn LLVMRustThinLTOBufferCreate(M: ModuleRef) -> *mut ThinLTOBuffer; + pub fn LLVMRustThinLTOBufferFree(M: *mut ThinLTOBuffer); + pub fn LLVMRustThinLTOBufferPtr(M: *const ThinLTOBuffer) -> *const c_char; + pub fn LLVMRustThinLTOBufferLen(M: *const ThinLTOBuffer) -> size_t; + pub fn LLVMRustCreateThinLTOData( + Modules: *const ThinLTOModule, + NumModules: c_uint, + PreservedSymbols: *const *const c_char, + PreservedSymbolsLen: c_uint, + ) -> *mut ThinLTOData; + pub fn LLVMRustPrepareThinLTORename( + Data: *const ThinLTOData, + Module: ModuleRef, + ) -> bool; + pub fn LLVMRustPrepareThinLTOResolveWeak( + Data: *const ThinLTOData, + Module: ModuleRef, + ) -> bool; + pub fn LLVMRustPrepareThinLTOInternalize( + Data: *const ThinLTOData, + Module: ModuleRef, + ) -> bool; + pub fn LLVMRustPrepareThinLTOImport( + Data: *const ThinLTOData, + Module: ModuleRef, + ) -> bool; + pub fn LLVMRustFreeThinLTOData(Data: *mut ThinLTOData); + pub fn LLVMRustParseBitcodeForThinLTO( + Context: ContextRef, + Data: *const u8, + len: usize, + Identifier: *const c_char, + ) -> ModuleRef; + pub fn LLVMGetModuleIdentifier(M: ModuleRef, size: *mut usize) -> *const c_char; + pub fn LLVMRustThinLTOGetDICompileUnit(M: ModuleRef, + CU1: *mut *mut c_void, + CU2: *mut *mut c_void); + pub fn LLVMRustThinLTOPatchDICompileUnit(M: ModuleRef, CU: *mut c_void); + + pub fn LLVMRustLinkerNew(M: ModuleRef) -> LinkerRef; + pub fn LLVMRustLinkerAdd(linker: LinkerRef, + bytecode: *const c_char, + bytecode_len: usize) -> bool; + pub fn LLVMRustLinkerFree(linker: LinkerRef); +} diff --git a/src/librustc_codegen_llvm/llvm/mod.rs b/src/librustc_codegen_llvm/llvm/mod.rs new file mode 100644 index 00000000000..b6ff9b17bd9 --- /dev/null +++ b/src/librustc_codegen_llvm/llvm/mod.rs @@ -0,0 +1,315 @@ +// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(dead_code)] +#![deny(bare_trait_objects)] + +pub use self::IntPredicate::*; +pub use self::RealPredicate::*; +pub use self::TypeKind::*; +pub use self::AtomicRmwBinOp::*; +pub use self::MetadataType::*; +pub use self::CodeGenOptSize::*; +pub use self::CallConv::*; +pub use self::Linkage::*; + +use std::str::FromStr; +use std::slice; +use std::ffi::{CString, CStr}; +use std::cell::RefCell; +use libc::{self, c_uint, c_char, size_t}; + +pub mod archive_ro; +pub mod diagnostic; +mod ffi; + +pub use self::ffi::*; + +impl LLVMRustResult { + pub fn into_result(self) -> Result<(), ()> { + match self { + LLVMRustResult::Success => Ok(()), + LLVMRustResult::Failure => Err(()), + } + } +} + +pub fn AddFunctionAttrStringValue(llfn: ValueRef, + idx: AttributePlace, + attr: &CStr, + value: &CStr) { + unsafe { + LLVMRustAddFunctionAttrStringValue(llfn, + idx.as_uint(), + attr.as_ptr(), + value.as_ptr()) + } +} + +#[derive(Copy, Clone)] +pub enum AttributePlace { + ReturnValue, + Argument(u32), + Function, +} + +impl AttributePlace { + pub fn as_uint(self) -> c_uint { + match self { + AttributePlace::ReturnValue => 0, + AttributePlace::Argument(i) => 1 + i, + AttributePlace::Function => !0, + } + } +} + +#[derive(Copy, Clone, PartialEq)] +#[repr(C)] +pub enum CodeGenOptSize { + CodeGenOptSizeNone = 0, + CodeGenOptSizeDefault = 1, + CodeGenOptSizeAggressive = 2, +} + +impl FromStr for ArchiveKind { + type Err = (); + + fn from_str(s: &str) -> Result<Self, Self::Err> { + match s { + "gnu" => Ok(ArchiveKind::K_GNU), + "bsd" => Ok(ArchiveKind::K_BSD), + "coff" => Ok(ArchiveKind::K_COFF), + _ => Err(()), + } + } +} + +#[allow(missing_copy_implementations)] +pub enum RustString_opaque {} +type RustStringRef = *mut RustString_opaque; +type RustStringRepr = *mut RefCell<Vec<u8>>; + +/// Appending to a Rust string -- used by RawRustStringOstream. +#[no_mangle] +pub unsafe extern "C" fn LLVMRustStringWriteImpl(sr: RustStringRef, + ptr: *const c_char, + size: size_t) { + let slice = slice::from_raw_parts(ptr as *const u8, size as usize); + + let sr = sr as RustStringRepr; + (*sr).borrow_mut().extend_from_slice(slice); +} + +pub fn SetInstructionCallConv(instr: ValueRef, cc: CallConv) { + unsafe { + LLVMSetInstructionCallConv(instr, cc as c_uint); + } +} +pub fn SetFunctionCallConv(fn_: ValueRef, cc: CallConv) { + unsafe { + LLVMSetFunctionCallConv(fn_, cc as c_uint); + } +} + +// Externally visible symbols that might appear in multiple codegen units need to appear in +// their own comdat section so that the duplicates can be discarded at link time. This can for +// example happen for generics when using multiple codegen units. This function simply uses the +// value's name as the comdat value to make sure that it is in a 1-to-1 relationship to the +// function. +// For more details on COMDAT sections see e.g. http://www.airs.com/blog/archives/52 +pub fn SetUniqueComdat(llmod: ModuleRef, val: ValueRef) { + unsafe { + LLVMRustSetComdat(llmod, val, LLVMGetValueName(val)); + } +} + +pub fn UnsetComdat(val: ValueRef) { + unsafe { + LLVMRustUnsetComdat(val); + } +} + +pub fn SetUnnamedAddr(global: ValueRef, unnamed: bool) { + unsafe { + LLVMSetUnnamedAddr(global, unnamed as Bool); + } +} + +pub fn set_thread_local(global: ValueRef, is_thread_local: bool) { + unsafe { + LLVMSetThreadLocal(global, is_thread_local as Bool); + } +} +pub fn set_thread_local_mode(global: ValueRef, mode: ThreadLocalMode) { + unsafe { + LLVMSetThreadLocalMode(global, mode); + } +} + +impl Attribute { + pub fn apply_llfn(&self, idx: AttributePlace, llfn: ValueRef) { + unsafe { LLVMRustAddFunctionAttribute(llfn, idx.as_uint(), *self) } + } + + pub fn apply_callsite(&self, idx: AttributePlace, callsite: ValueRef) { + unsafe { LLVMRustAddCallSiteAttribute(callsite, idx.as_uint(), *self) } + } + + pub fn unapply_llfn(&self, idx: AttributePlace, llfn: ValueRef) { + unsafe { LLVMRustRemoveFunctionAttributes(llfn, idx.as_uint(), *self) } + } + + 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. + +struct TargetData { + lltd: TargetDataRef, +} + +impl Drop for TargetData { + fn drop(&mut self) { + unsafe { + LLVMDisposeTargetData(self.lltd); + } + } +} + +fn mk_target_data(string_rep: &str) -> TargetData { + let string_rep = CString::new(string_rep).unwrap(); + TargetData { lltd: unsafe { LLVMCreateTargetData(string_rep.as_ptr()) } } +} + +// Memory-managed interface to object files. + +pub struct ObjectFile { + pub llof: ObjectFileRef, +} + +unsafe impl Send for ObjectFile {} + +impl ObjectFile { + // This will take ownership of llmb + pub fn new(llmb: MemoryBufferRef) -> Option<ObjectFile> { + unsafe { + let llof = LLVMCreateObjectFile(llmb); + if llof as isize == 0 { + // LLVMCreateObjectFile took ownership of llmb + return None; + } + + Some(ObjectFile { llof: llof }) + } + } +} + +impl Drop for ObjectFile { + fn drop(&mut self) { + unsafe { + LLVMDisposeObjectFile(self.llof); + } + } +} + +// Memory-managed interface to section iterators. + +pub struct SectionIter { + pub llsi: SectionIteratorRef, +} + +impl Drop for SectionIter { + fn drop(&mut self) { + unsafe { + LLVMDisposeSectionIterator(self.llsi); + } + } +} + +pub fn mk_section_iter(llof: ObjectFileRef) -> SectionIter { + unsafe { SectionIter { llsi: LLVMGetSections(llof) } } +} + +/// Safe wrapper around `LLVMGetParam`, because segfaults are no fun. +pub fn get_param(llfn: ValueRef, index: c_uint) -> ValueRef { + unsafe { + assert!(index < LLVMCountParams(llfn), + "out of bounds argument access: {} out of {} arguments", index, LLVMCountParams(llfn)); + LLVMGetParam(llfn, index) + } +} + +fn get_params(llfn: ValueRef) -> Vec<ValueRef> { + unsafe { + let num_params = LLVMCountParams(llfn); + (0..num_params).map(|idx| LLVMGetParam(llfn, idx)).collect() + } +} + +pub fn build_string<F>(f: F) -> Option<String> + where F: FnOnce(RustStringRef) +{ + let mut buf = RefCell::new(Vec::new()); + f(&mut buf as RustStringRepr as RustStringRef); + String::from_utf8(buf.into_inner()).ok() +} + +pub unsafe fn twine_to_string(tr: TwineRef) -> String { + build_string(|s| LLVMRustWriteTwineToString(tr, s)).expect("got a non-UTF8 Twine from LLVM") +} + +pub fn last_error() -> Option<String> { + unsafe { + let cstr = LLVMRustGetLastError(); + if cstr.is_null() { + None + } else { + let err = CStr::from_ptr(cstr).to_bytes(); + let err = String::from_utf8_lossy(err).to_string(); + libc::free(cstr as *mut _); + Some(err) + } + } +} + +pub struct OperandBundleDef { + inner: OperandBundleDefRef, +} + +impl OperandBundleDef { + pub fn new(name: &str, vals: &[ValueRef]) -> OperandBundleDef { + let name = CString::new(name).unwrap(); + let def = unsafe { + LLVMRustBuildOperandBundleDef(name.as_ptr(), vals.as_ptr(), vals.len() as c_uint) + }; + OperandBundleDef { inner: def } + } + + pub fn raw(&self) -> OperandBundleDefRef { + self.inner + } +} + +impl Drop for OperandBundleDef { + fn drop(&mut self) { + unsafe { + LLVMRustFreeOperandBundleDef(self.inner); + } + } +} |
