diff options
Diffstat (limited to 'src/librustc_llvm/lib.rs')
| -rw-r--r-- | src/librustc_llvm/lib.rs | 318 |
1 files changed, 3 insertions, 315 deletions
diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs index 91f9b4ac03b..76ec5b53523 100644 --- a/src/librustc_llvm/lib.rs +++ b/src/librustc_llvm/lib.rs @@ -8,290 +8,18 @@ // 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)] - #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "https://doc.rust-lang.org/nightly/")] -#![feature(box_syntax)] -#![feature(concat_idents)] -#![feature(libc)] -#![feature(link_args)] -#![feature(static_nobundle)] - // See librustc_cratesio_shim/Cargo.toml for a comment explaining this. #[allow(unused_extern_crates)] extern crate rustc_cratesio_shim; -#[macro_use] -extern crate bitflags; -extern crate libc; - -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::{c_uint, c_char, size_t}; - -pub mod archive_ro; -pub mod diagnostic; -mod ffi; - -pub use 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") -} +// NOTE: This crate only exists to allow linking on mingw targets. +/// Initialize targets enabled by the build script via `cfg(llvm_component = "...")`. +/// NB: this function can't be moved to `rustc_codegen_llvm` because of the `cfg`s. pub fn initialize_available_targets() { macro_rules! init_target( ($cfg:meta, $($method:ident),*) => { { @@ -383,43 +111,3 @@ pub fn initialize_available_targets() { LLVMInitializeWebAssemblyTargetMC, LLVMInitializeWebAssemblyAsmPrinter); } - -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); - } - } -} |
