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 | |
| parent | 54628c8ea844956f3f4f416b82067c634eb09f7b (diff) | |
| download | rust-077be49bde25ca92dc03c86c805438609133a82a.tar.gz rust-077be49bde25ca92dc03c86c805438609133a82a.zip | |
rustc_llvm: move to rustc_codegen_llvm::llvm.
| -rw-r--r-- | src/Cargo.lock | 3 | ||||
| -rw-r--r-- | src/librustc_codegen_llvm/lib.rs | 6 | ||||
| -rw-r--r-- | src/librustc_codegen_llvm/llvm/archive_ro.rs (renamed from src/librustc_llvm/archive_ro.rs) | 28 | ||||
| -rw-r--r-- | src/librustc_codegen_llvm/llvm/diagnostic.rs (renamed from src/librustc_llvm/diagnostic.rs) | 2 | ||||
| -rw-r--r-- | src/librustc_codegen_llvm/llvm/ffi.rs (renamed from src/librustc_llvm/ffi.rs) | 19 | ||||
| -rw-r--r-- | src/librustc_codegen_llvm/llvm/mod.rs | 315 | ||||
| -rw-r--r-- | src/librustc_codegen_llvm/llvm_util.rs | 2 | ||||
| -rw-r--r-- | src/librustc_llvm/Cargo.toml | 5 | ||||
| -rw-r--r-- | src/librustc_llvm/lib.rs | 318 | ||||
| -rw-r--r-- | src/librustc_target/lib.rs | 6 | ||||
| -rw-r--r-- | src/rustllvm/ArchiveWrapper.cpp | 2 |
11 files changed, 348 insertions, 358 deletions
diff --git a/src/Cargo.lock b/src/Cargo.lock index 89daa8e09c7..be32872dad8 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -2222,11 +2222,8 @@ dependencies = [ name = "rustc_llvm" version = "0.0.0" dependencies = [ - "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "build_helper 0.1.0", "cc 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_cratesio_shim 0.0.0", ] [[package]] diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs index 90f96c9687b..14ec81fc665 100644 --- a/src/librustc_codegen_llvm/lib.rs +++ b/src/librustc_codegen_llvm/lib.rs @@ -29,6 +29,9 @@ #![feature(rustc_diagnostic_macros)] #![feature(slice_sort_by_cached_key)] #![feature(optin_builtin_traits)] +#![feature(concat_idents)] +#![feature(link_args)] +#![feature(static_nobundle)] use rustc::dep_graph::WorkProduct; use syntax_pos::symbol::Symbol; @@ -46,7 +49,7 @@ extern crate rustc_target; #[macro_use] extern crate rustc_data_structures; extern crate rustc_demangle; extern crate rustc_incremental; -extern crate rustc_llvm as llvm; +extern crate rustc_llvm; extern crate rustc_platform_intrinsics as intrinsics; extern crate rustc_codegen_utils; @@ -110,6 +113,7 @@ mod debuginfo; mod declare; mod glue; mod intrinsic; +pub mod llvm; mod llvm_util; mod metadata; mod meth; diff --git a/src/librustc_llvm/archive_ro.rs b/src/librustc_codegen_llvm/llvm/archive_ro.rs index 9d869007270..116f16de324 100644 --- a/src/librustc_llvm/archive_ro.rs +++ b/src/librustc_codegen_llvm/llvm/archive_ro.rs @@ -10,7 +10,7 @@ //! A wrapper around LLVM's archive (.a) code -use ArchiveRef; +use super::ArchiveRef; use std::ffi::CString; use std::marker; @@ -26,11 +26,11 @@ unsafe impl Send for ArchiveRO {} pub struct Iter<'a> { archive: &'a ArchiveRO, - ptr: ::ArchiveIteratorRef, + ptr: super::ArchiveIteratorRef, } pub struct Child<'a> { - ptr: ::ArchiveChildRef, + ptr: super::ArchiveChildRef, _data: marker::PhantomData<&'a ArchiveRO>, } @@ -44,9 +44,9 @@ impl ArchiveRO { pub fn open(dst: &Path) -> Result<ArchiveRO, String> { return unsafe { let s = path2cstr(dst); - let ar = ::LLVMRustOpenArchive(s.as_ptr()); + let ar = super::LLVMRustOpenArchive(s.as_ptr()); if ar.is_null() { - Err(::last_error().unwrap_or("failed to open archive".to_string())) + Err(super::last_error().unwrap_or("failed to open archive".to_string())) } else { Ok(ArchiveRO { ptr: ar }) } @@ -72,7 +72,7 @@ impl ArchiveRO { pub fn iter(&self) -> Iter { unsafe { Iter { - ptr: ::LLVMRustArchiveIteratorNew(self.ptr), + ptr: super::LLVMRustArchiveIteratorNew(self.ptr), archive: self, } } @@ -82,7 +82,7 @@ impl ArchiveRO { impl Drop for ArchiveRO { fn drop(&mut self) { unsafe { - ::LLVMRustDestroyArchive(self.ptr); + super::LLVMRustDestroyArchive(self.ptr); } } } @@ -91,9 +91,9 @@ impl<'a> Iterator for Iter<'a> { type Item = Result<Child<'a>, String>; fn next(&mut self) -> Option<Result<Child<'a>, String>> { - let ptr = unsafe { ::LLVMRustArchiveIteratorNext(self.ptr) }; + let ptr = unsafe { super::LLVMRustArchiveIteratorNext(self.ptr) }; if ptr.is_null() { - ::last_error().map(Err) + super::last_error().map(Err) } else { Some(Ok(Child { ptr, @@ -106,7 +106,7 @@ impl<'a> Iterator for Iter<'a> { impl<'a> Drop for Iter<'a> { fn drop(&mut self) { unsafe { - ::LLVMRustArchiveIteratorFree(self.ptr); + super::LLVMRustArchiveIteratorFree(self.ptr); } } } @@ -115,7 +115,7 @@ impl<'a> Child<'a> { pub fn name(&self) -> Option<&'a str> { unsafe { let mut name_len = 0; - let name_ptr = ::LLVMRustArchiveChildName(self.ptr, &mut name_len); + let name_ptr = super::LLVMRustArchiveChildName(self.ptr, &mut name_len); if name_ptr.is_null() { None } else { @@ -128,7 +128,7 @@ impl<'a> Child<'a> { pub fn data(&self) -> &'a [u8] { unsafe { let mut data_len = 0; - let data_ptr = ::LLVMRustArchiveChildData(self.ptr, &mut data_len); + let data_ptr = super::LLVMRustArchiveChildData(self.ptr, &mut data_len); if data_ptr.is_null() { panic!("failed to read data from archive child"); } @@ -136,7 +136,7 @@ impl<'a> Child<'a> { } } - pub fn raw(&self) -> ::ArchiveChildRef { + pub fn raw(&self) -> super::ArchiveChildRef { self.ptr } } @@ -144,7 +144,7 @@ impl<'a> Child<'a> { impl<'a> Drop for Child<'a> { fn drop(&mut self) { unsafe { - ::LLVMRustArchiveChildFree(self.ptr); + super::LLVMRustArchiveChildFree(self.ptr); } } } diff --git a/src/librustc_llvm/diagnostic.rs b/src/librustc_codegen_llvm/llvm/diagnostic.rs index e73c570ed82..0674bccd51e 100644 --- a/src/librustc_llvm/diagnostic.rs +++ b/src/librustc_codegen_llvm/llvm/diagnostic.rs @@ -16,7 +16,7 @@ pub use self::Diagnostic::*; use libc::c_uint; use std::ptr; -use {DiagnosticInfoRef, TwineRef, ValueRef}; +use super::{DiagnosticInfoRef, TwineRef, ValueRef}; #[derive(Copy, Clone)] pub enum OptimizationDiagnosticKind { diff --git a/src/librustc_llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index 8d04438eea2..afd1070a77e 100644 --- a/src/librustc_llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -14,15 +14,17 @@ // This method was changed in this LLVM patch: // https://reviews.llvm.org/D26769 -use debuginfo::{DIBuilderRef, DIDescriptor, DIFile, DILexicalBlock, DISubprogram, DIType, - DIBasicType, DIDerivedType, DICompositeType, DIScope, DIVariable, - DIGlobalVariable, DIArray, DISubrange, DITemplateTypeParameter, DIEnumerator, - DINameSpace, DIFlags}; +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 RustStringRef; +use super::RustStringRef; pub type Opcode = u32; pub type Bool = c_uint; @@ -512,13 +514,6 @@ pub mod debuginfo { pub enum ModuleBuffer {} -// This annotation is primarily needed for MSVC where attributes like -// dllimport/dllexport are applied and need to be correct for everything to -// link successfully. The #[link] annotation here says "these symbols are -// included statically" which means that they're all exported with dllexport -// and from the rustc_llvm dynamic library. Otherwise the rustc_codegen_llvm dynamic -// library would not be able to access these symbols. -#[link(name = "rustllvm", kind = "static")] extern "C" { // Create and destroy contexts. pub fn LLVMRustContextCreate(shouldDiscardNames: bool) -> ContextRef; 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); + } + } +} diff --git a/src/librustc_codegen_llvm/llvm_util.rs b/src/librustc_codegen_llvm/llvm_util.rs index e941998098d..441fff5f08c 100644 --- a/src/librustc_codegen_llvm/llvm_util.rs +++ b/src/librustc_codegen_llvm/llvm_util.rs @@ -73,7 +73,7 @@ unsafe fn configure_llvm(sess: &Session) { llvm::LLVMInitializePasses(); - llvm::initialize_available_targets(); + ::rustc_llvm::initialize_available_targets(); llvm::LLVMRustSetLLVMOptions(llvm_args.len() as c_int, llvm_args.as_ptr()); diff --git a/src/librustc_llvm/Cargo.toml b/src/librustc_llvm/Cargo.toml index 0978c2ceb14..013badb71cc 100644 --- a/src/librustc_llvm/Cargo.toml +++ b/src/librustc_llvm/Cargo.toml @@ -12,11 +12,6 @@ path = "lib.rs" static-libstdcpp = [] emscripten = [] -[dependencies] -bitflags = "1.0" -libc = "0.2" -rustc_cratesio_shim = { path = "../librustc_cratesio_shim" } - [build-dependencies] build_helper = { path = "../build_helper" } cc = "1.0.1" 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); - } - } -} diff --git a/src/librustc_target/lib.rs b/src/librustc_target/lib.rs index 8f491157439..a50a5a2d1cb 100644 --- a/src/librustc_target/lib.rs +++ b/src/librustc_target/lib.rs @@ -15,11 +15,7 @@ //! is really just odds-and-ends relating to code gen and linking. //! This crate mostly exists to make rustc smaller, so we might put //! more 'stuff' here in the future. It does not have a dependency on -//! rustc_llvm. -//! -//! FIXME: Split this into two crates: one that has deps on syntax, and -//! one that doesn't; the one that doesn't might get decent parallel -//! build speedups. +//! LLVM. #