From 077be49bde25ca92dc03c86c805438609133a82a Mon Sep 17 00:00:00 2001 From: Irina Popa Date: Tue, 29 May 2018 20:41:36 +0300 Subject: [PATCH 01/36] rustc_llvm: move to rustc_codegen_llvm::llvm. --- src/Cargo.lock | 3 - src/librustc_codegen_llvm/lib.rs | 6 +- .../llvm}/archive_ro.rs | 28 +- .../llvm}/diagnostic.rs | 2 +- .../llvm}/ffi.rs | 19 +- src/librustc_codegen_llvm/llvm/mod.rs | 315 +++++++++++++++++ src/librustc_codegen_llvm/llvm_util.rs | 2 +- src/librustc_llvm/Cargo.toml | 5 - src/librustc_llvm/lib.rs | 318 +----------------- src/librustc_target/lib.rs | 6 +- src/rustllvm/ArchiveWrapper.cpp | 2 +- 11 files changed, 348 insertions(+), 358 deletions(-) rename src/{librustc_llvm => librustc_codegen_llvm/llvm}/archive_ro.rs (80%) rename src/{librustc_llvm => librustc_codegen_llvm/llvm}/diagnostic.rs (99%) rename src/{librustc_llvm => librustc_codegen_llvm/llvm}/ffi.rs (98%) create mode 100644 src/librustc_codegen_llvm/llvm/mod.rs diff --git a/src/Cargo.lock b/src/Cargo.lock index 89daa8e09c7d1..be32872dad80a 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 90f96c9687bc1..14ec81fc6655b 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 similarity index 80% rename from src/librustc_llvm/archive_ro.rs rename to src/librustc_codegen_llvm/llvm/archive_ro.rs index 9d8690072709b..116f16de324be 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 { 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, String>; fn next(&mut self) -> Option, 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 similarity index 99% rename from src/librustc_llvm/diagnostic.rs rename to src/librustc_codegen_llvm/llvm/diagnostic.rs index e73c570ed8231..0674bccd51e87 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 similarity index 98% rename from src/librustc_llvm/ffi.rs rename to src/librustc_codegen_llvm/llvm/ffi.rs index 8d04438eea290..afd1070a77ed7 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 0000000000000..b6ff9b17bd933 --- /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 or the MIT license +// , 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 { + 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>; + +/// 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 { + 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 { + unsafe { + let num_params = LLVMCountParams(llfn); + (0..num_params).map(|idx| LLVMGetParam(llfn, idx)).collect() + } +} + +pub fn build_string(f: F) -> Option + 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 { + 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 e941998098d00..441fff5f08c8f 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 0978c2ceb141d..013badb71cc5a 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 91f9b4ac03b86..76ec5b5352309 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 { - 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>; - -/// 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 { - 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 { - unsafe { - let num_params = LLVMCountParams(llfn); - - (0..num_params).map(|idx| LLVMGetParam(llfn, idx)).collect() - } -} - -pub fn build_string(f: F) -> Option - 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 { - 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 8f4911574398b..a50a5a2d1cbe7 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. #![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", diff --git a/src/rustllvm/ArchiveWrapper.cpp b/src/rustllvm/ArchiveWrapper.cpp index 93157cd681942..49a4962858ca7 100644 --- a/src/rustllvm/ArchiveWrapper.cpp +++ b/src/rustllvm/ArchiveWrapper.cpp @@ -148,7 +148,7 @@ LLVMRustArchiveChildName(LLVMRustArchiveChildConstRef Child, size_t *Size) { #if LLVM_VERSION_GE(4, 0) Expected NameOrErr = Child->getName(); if (!NameOrErr) { - // rustc_llvm currently doesn't use this error string, but it might be + // rustc_codegen_llvm currently doesn't use this error string, but it might be // useful in the future, and in the mean time this tells LLVM that the // error was not ignored and that it shouldn't abort the process. LLVMRustSetLastError(toString(NameOrErr.takeError()).c_str()); From af04e9426c71ac1050b9007c93b03864e45a81df Mon Sep 17 00:00:00 2001 From: Irina Popa Date: Wed, 27 Jun 2018 13:12:47 +0300 Subject: [PATCH 02/36] rustc_codegen_llvm: move from empty enums to extern types. --- src/librustc_codegen_llvm/allocator.rs | 3 +- src/librustc_codegen_llvm/back/archive.rs | 8 +- src/librustc_codegen_llvm/builder.rs | 13 +- src/librustc_codegen_llvm/context.rs | 11 +- .../debuginfo/create_scope_map.rs | 20 +-- src/librustc_codegen_llvm/debuginfo/gdb.rs | 3 +- .../debuginfo/metadata.rs | 58 +++---- src/librustc_codegen_llvm/debuginfo/mod.rs | 23 +-- .../debuginfo/namespace.rs | 8 +- .../debuginfo/source_loc.rs | 14 +- src/librustc_codegen_llvm/debuginfo/utils.rs | 5 +- src/librustc_codegen_llvm/lib.rs | 1 + src/librustc_codegen_llvm/llvm/diagnostic.rs | 7 +- src/librustc_codegen_llvm/llvm/ffi.rs | 148 ++++++++---------- src/librustc_codegen_llvm/mir/mod.rs | 25 +-- src/librustc_codegen_llvm/mir/operand.rs | 3 +- src/librustc_codegen_llvm/mir/place.rs | 10 +- src/librustc_codegen_llvm/type_.rs | 15 +- 18 files changed, 178 insertions(+), 197 deletions(-) diff --git a/src/librustc_codegen_llvm/allocator.rs b/src/librustc_codegen_llvm/allocator.rs index eeb02e948f1cc..49cdbf34fa95a 100644 --- a/src/librustc_codegen_llvm/allocator.rs +++ b/src/librustc_codegen_llvm/allocator.rs @@ -9,7 +9,6 @@ // except according to those terms. use std::ffi::CString; -use std::ptr; use attributes; use libc::c_uint; @@ -90,7 +89,7 @@ pub(crate) unsafe fn codegen(tcx: TyCtxt, mods: &ModuleLlvm, kind: AllocatorKind callee, args.as_ptr(), args.len() as c_uint, - ptr::null_mut(), + None, "\0".as_ptr() as *const _); llvm::LLVMSetTailCall(ret, True); if output.is_some() { diff --git a/src/librustc_codegen_llvm/back/archive.rs b/src/librustc_codegen_llvm/back/archive.rs index b99835cb5c649..4ea97911830c7 100644 --- a/src/librustc_codegen_llvm/back/archive.rs +++ b/src/librustc_codegen_llvm/back/archive.rs @@ -14,7 +14,7 @@ use std::ffi::{CString, CStr}; use std::io; use std::mem; use std::path::{Path, PathBuf}; -use std::ptr; +use std::ptr::{self, NonNull}; use std::str; use back::bytecode::RLIB_BYTECODE_EXTENSION; @@ -246,7 +246,7 @@ impl<'a> ArchiveBuilder<'a> { let name = CString::new(child_name)?; members.push(llvm::LLVMRustArchiveMemberNew(ptr::null(), name.as_ptr(), - child.raw())); + NonNull::new(child.raw()))); strings.push(name); } } @@ -257,7 +257,7 @@ impl<'a> ArchiveBuilder<'a> { let name = CString::new(name_in_archive)?; members.push(llvm::LLVMRustArchiveMemberNew(path.as_ptr(), name.as_ptr(), - ptr::null_mut())); + None)); strings.push(path); strings.push(name); } @@ -284,7 +284,7 @@ impl<'a> ArchiveBuilder<'a> { let name = CString::new(child_name)?; let m = llvm::LLVMRustArchiveMemberNew(ptr::null(), name.as_ptr(), - child.raw()); + NonNull::new(child.raw())); members.push(m); strings.push(name); } diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index b34d0f1cd9070..5f460a14ef987 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -26,6 +26,7 @@ use std::borrow::Cow; use std::ffi::CString; use std::ops::Range; use std::ptr; +use std::ptr::NonNull; use syntax_pos::Span; // All Builders must have an llfn associated with them @@ -211,7 +212,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { .join(", ")); let args = self.check_call("invoke", llfn, args); - let bundle = bundle.as_ref().map(|b| b.raw()).unwrap_or(ptr::null_mut()); + let bundle = bundle.as_ref().and_then(|b| NonNull::new(b.raw())); unsafe { llvm::LLVMRustBuildInvoke(self.llbuilder, @@ -909,7 +910,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { .join(", ")); let args = self.check_call("call", llfn, args); - let bundle = bundle.as_ref().map(|b| b.raw()).unwrap_or(ptr::null_mut()); + let bundle = bundle.as_ref().and_then(|b| NonNull::new(b.raw())); unsafe { llvm::LLVMRustBuildCall(self.llbuilder, llfn, args.as_ptr(), @@ -1196,7 +1197,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { parent: Option, args: &[ValueRef]) -> ValueRef { self.count_insn("cleanuppad"); - let parent = parent.unwrap_or(ptr::null_mut()); + let parent = parent.and_then(NonNull::new); let name = CString::new("cleanuppad").unwrap(); let ret = unsafe { llvm::LLVMRustBuildCleanupPad(self.llbuilder, @@ -1212,7 +1213,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { pub fn cleanup_ret(&self, cleanup: ValueRef, unwind: Option) -> ValueRef { self.count_insn("cleanupret"); - let unwind = unwind.unwrap_or(ptr::null_mut()); + let unwind = unwind.and_then(NonNull::new); let ret = unsafe { llvm::LLVMRustBuildCleanupRet(self.llbuilder, cleanup, unwind) }; @@ -1248,8 +1249,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { unwind: Option, num_handlers: usize) -> ValueRef { self.count_insn("catchswitch"); - let parent = parent.unwrap_or(ptr::null_mut()); - let unwind = unwind.unwrap_or(ptr::null_mut()); + let parent = parent.and_then(NonNull::new); + let unwind = unwind.and_then(NonNull::new); let name = CString::new("catchswitch").unwrap(); let ret = unsafe { llvm::LLVMRustBuildCatchSwitch(self.llbuilder, parent, unwind, diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs index b774d7c5def21..130e14c976dee 100644 --- a/src/librustc_codegen_llvm/context.rs +++ b/src/librustc_codegen_llvm/context.rs @@ -35,7 +35,6 @@ use rustc_target::spec::{HasTargetSpec, Target}; use std::ffi::{CStr, CString}; use std::cell::{Cell, RefCell}; -use std::ptr; use std::iter; use std::str; use std::sync::Arc; @@ -280,7 +279,9 @@ impl<'a, 'tcx> CodegenCx<'a, 'tcx> { None }; - let mut cx = CodegenCx { + let isize_ty = Type::ix_llcx(llcx, tcx.data_layout.pointer_size.bits()); + + CodegenCx { tcx, check_overflow, use_dll_storage_attrs, @@ -300,16 +301,14 @@ impl<'a, 'tcx> CodegenCx<'a, 'tcx> { lltypes: RefCell::new(FxHashMap()), scalar_lltypes: RefCell::new(FxHashMap()), pointee_infos: RefCell::new(FxHashMap()), - isize_ty: Type::from_ref(ptr::null_mut()), + isize_ty, dbg_cx, eh_personality: Cell::new(None), eh_unwind_resume: Cell::new(None), rust_try_fn: Cell::new(None), intrinsics: RefCell::new(FxHashMap()), local_gen_sym_counter: Cell::new(0), - }; - cx.isize_ty = Type::isize(&cx); - cx + } } } diff --git a/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs b/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs index fcde7f9bbc33d..dc92363a83354 100644 --- a/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs +++ b/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs @@ -13,12 +13,12 @@ use super::metadata::file_metadata; use super::utils::{DIB, span_start}; use llvm; -use llvm::debuginfo::DIScope; +use llvm::debuginfo::DIScope_opaque; use common::CodegenCx; use rustc::mir::{Mir, SourceScope}; +use std::ptr::NonNull; use libc::c_uint; -use std::ptr; use syntax_pos::Pos; @@ -29,7 +29,7 @@ use syntax_pos::BytePos; #[derive(Clone, Copy, Debug)] pub struct MirDebugScope { - pub scope_metadata: DIScope, + pub scope_metadata: Option>, // Start and end offsets of the file to which this DIScope belongs. // These are used to quickly determine whether some span refers to the same file. pub file_start_pos: BytePos, @@ -38,7 +38,7 @@ pub struct MirDebugScope { impl MirDebugScope { pub fn is_valid(&self) -> bool { - !self.scope_metadata.is_null() + !self.scope_metadata.is_none() } } @@ -47,7 +47,7 @@ impl MirDebugScope { pub fn create_mir_scopes(cx: &CodegenCx, mir: &Mir, debug_context: &FunctionDebugContext) -> IndexVec { let null_scope = MirDebugScope { - scope_metadata: ptr::null_mut(), + scope_metadata: None, file_start_pos: BytePos(0), file_end_pos: BytePos(0) }; @@ -95,7 +95,7 @@ fn make_mir_scope(cx: &CodegenCx, // The root is the function itself. let loc = span_start(cx, mir.span); scopes[scope] = MirDebugScope { - scope_metadata: debug_context.fn_metadata, + scope_metadata: NonNull::new(debug_context.fn_metadata), file_start_pos: loc.file.start_pos, file_end_pos: loc.file.end_pos, }; @@ -109,7 +109,7 @@ fn make_mir_scope(cx: &CodegenCx, // However, we don't skip creating a nested scope if // our parent is the root, because we might want to // put arguments in the root and not have shadowing. - if parent_scope.scope_metadata != debug_context.fn_metadata { + if parent_scope.scope_metadata.unwrap().as_ptr() != debug_context.fn_metadata { scopes[scope] = parent_scope; return; } @@ -121,12 +121,12 @@ fn make_mir_scope(cx: &CodegenCx, debug_context.defining_crate); let scope_metadata = unsafe { - llvm::LLVMRustDIBuilderCreateLexicalBlock( + NonNull::new(llvm::LLVMRustDIBuilderCreateLexicalBlock( DIB(cx), - parent_scope.scope_metadata, + parent_scope.scope_metadata.unwrap().as_ptr(), file_metadata, loc.line as c_uint, - loc.col.to_usize() as c_uint) + loc.col.to_usize() as c_uint)) }; scopes[scope] = MirDebugScope { scope_metadata, diff --git a/src/librustc_codegen_llvm/debuginfo/gdb.rs b/src/librustc_codegen_llvm/debuginfo/gdb.rs index 0b4858c7ab051..4014ad95b9dd0 100644 --- a/src/librustc_codegen_llvm/debuginfo/gdb.rs +++ b/src/librustc_codegen_llvm/debuginfo/gdb.rs @@ -18,7 +18,6 @@ use declare; use type_::Type; use rustc::session::config::NoDebugInfo; -use std::ptr; use syntax::attr; @@ -50,7 +49,7 @@ pub fn get_or_insert_gdb_debug_scripts_section_global(cx: &CodegenCx) c_section_var_name.as_ptr() as *const _) }; - if section_var == ptr::null_mut() { + if section_var.is_null() { let section_name = b".debug_gdb_scripts\0"; let section_contents = b"\x01gdb_load_rust_pretty_printers.py\0"; diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs index 2f4dd5a7ce5bb..59c14a6910ba2 100644 --- a/src/librustc_codegen_llvm/debuginfo/metadata.rs +++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs @@ -20,7 +20,7 @@ use super::{CrateDebugContext}; use abi; use llvm::{self, ValueRef}; -use llvm::debuginfo::{DIType, DIFile, DIScope, DIDescriptor, +use llvm::debuginfo::{DIType, DIFile, DIScope_opaque, DIScope, DIDescriptor, DICompositeType, DILexicalBlock, DIFlags}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; @@ -41,6 +41,7 @@ use std::ffi::CString; use std::fmt::Write; use std::iter; use std::ptr; +use std::ptr::NonNull; use std::path::{Path, PathBuf}; use syntax::ast; use syntax::symbol::{Interner, InternedString, Symbol}; @@ -64,8 +65,7 @@ const DW_ATE_unsigned_char: c_uint = 0x08; pub const UNKNOWN_LINE_NUMBER: c_uint = 0; pub const UNKNOWN_COLUMN_NUMBER: c_uint = 0; -// ptr::null() doesn't work :( -pub const NO_SCOPE_METADATA: DIScope = (0 as DIScope); +pub const NO_SCOPE_METADATA: Option> = None; #[derive(Copy, Debug, Hash, Eq, PartialEq, Clone)] pub struct UniqueTypeId(ast::Name); @@ -289,7 +289,7 @@ fn fixed_vec_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, }; let subrange = unsafe { - llvm::LLVMRustDIBuilderGetOrCreateSubrange(DIB(cx), 0, upper_bound) + NonNull::new(llvm::LLVMRustDIBuilderGetOrCreateSubrange(DIB(cx), 0, upper_bound)) }; let subscripts = create_DIArray(DIB(cx), &[subrange]); @@ -365,15 +365,17 @@ fn subroutine_type_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, &signature, ); - let signature_metadata: Vec = iter::once( + let signature_metadata: Vec<_> = iter::once( // return type match signature.output().sty { - ty::TyTuple(ref tys) if tys.is_empty() => ptr::null_mut(), - _ => type_metadata(cx, signature.output(), span) + ty::TyTuple(ref tys) if tys.is_empty() => None, + _ => NonNull::new(type_metadata(cx, signature.output(), span)) } ).chain( // regular arguments - signature.inputs().iter().map(|argument_type| type_metadata(cx, argument_type, span)) + signature.inputs().iter().map(|argument_type| { + NonNull::new(type_metadata(cx, argument_type, span)) + }) ).collect(); return_if_metadata_created_in_meantime!(cx, unique_type_id); @@ -406,7 +408,7 @@ fn trait_pointer_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, let containing_scope = match trait_type.sty { ty::TyDynamic(ref data, ..) => if let Some(principal) = data.principal() { let def_id = principal.def_id(); - get_namespace_for_item(cx, def_id) + NonNull::new(get_namespace_for_item(cx, def_id)) } else { NO_SCOPE_METADATA }, @@ -985,7 +987,7 @@ fn prepare_struct_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, struct_type, &struct_name, unique_type_id, - containing_scope); + NonNull::new(containing_scope)); create_and_register_recursive_type_forward_declaration( cx, @@ -1317,7 +1319,7 @@ fn describe_enum_variant<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, layout.ty, &variant_name, unique_type_id, - containing_scope); + NonNull::new(containing_scope)); // If this is not a univariant enum, there is also the discriminant field. let (discr_offset, discr_arg) = match discriminant_info { @@ -1376,17 +1378,17 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, let file_metadata = unknown_file_metadata(cx); let def = enum_type.ty_adt_def().unwrap(); - let enumerators_metadata: Vec = def.discriminants(cx.tcx) + let enumerators_metadata: Vec<_> = def.discriminants(cx.tcx) .zip(&def.variants) .map(|(discr, v)| { let token = v.name.as_str(); let name = CString::new(token.as_bytes()).unwrap(); unsafe { - llvm::LLVMRustDIBuilderCreateEnumerator( + NonNull::new(llvm::LLVMRustDIBuilderCreateEnumerator( DIB(cx), name.as_ptr(), // FIXME: what if enumeration has i128 discriminant? - discr.val as u64) + discr.val as u64)) } }) .collect(); @@ -1459,7 +1461,7 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, enum_type_size.bits(), enum_type_align.abi_bits() as u32, DIFlags::FlagZero, - ptr::null_mut(), + None, 0, // RuntimeLang unique_type_id_str.as_ptr()) }; @@ -1494,7 +1496,7 @@ fn composite_type_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, composite_type_name: &str, composite_type_unique_id: UniqueTypeId, member_descriptions: &[MemberDescription], - containing_scope: DIScope, + containing_scope: Option>, // Ignore source location information as long as it // can't be reconstructed for non-local crates. @@ -1535,13 +1537,13 @@ fn set_members_of_composite_type(cx: &CodegenCx, } } - let member_metadata: Vec = member_descriptions + let member_metadata: Vec<_> = member_descriptions .iter() .map(|member_description| { let member_name = member_description.name.as_bytes(); let member_name = CString::new(member_name).unwrap(); unsafe { - llvm::LLVMRustDIBuilderCreateMemberType( + NonNull::new(llvm::LLVMRustDIBuilderCreateMemberType( DIB(cx), composite_type_metadata, member_name.as_ptr(), @@ -1551,7 +1553,7 @@ fn set_members_of_composite_type(cx: &CodegenCx, member_description.align.abi_bits() as u32, member_description.offset.bits(), member_description.flags, - member_description.type_metadata) + member_description.type_metadata)) } }) .collect(); @@ -1570,7 +1572,7 @@ fn create_struct_stub<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, struct_type: Ty<'tcx>, struct_type_name: &str, unique_type_id: UniqueTypeId, - containing_scope: DIScope) + containing_scope: Option>) -> DICompositeType { let (struct_size, struct_align) = cx.size_and_align_of(struct_type); @@ -1593,10 +1595,10 @@ fn create_struct_stub<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, struct_size.bits(), struct_align.abi_bits() as u32, DIFlags::FlagZero, - ptr::null_mut(), + None, empty_array, 0, - ptr::null_mut(), + None, unique_type_id.as_ptr()) }; @@ -1630,7 +1632,7 @@ fn create_union_stub<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, union_size.bits(), union_align.abi_bits() as u32, DIFlags::FlagZero, - empty_array, + NonNull::new(empty_array), 0, // RuntimeLang unique_type_id.as_ptr()) }; @@ -1684,7 +1686,7 @@ pub fn create_global_var_metadata(cx: &CodegenCx, unsafe { llvm::LLVMRustDIBuilderCreateStaticVariable(DIB(cx), - var_scope, + NonNull::new(var_scope), var_name.as_ptr(), // If null, linkage_name field is omitted, // which is what we want for no_mangle statics @@ -1695,7 +1697,7 @@ pub fn create_global_var_metadata(cx: &CodegenCx, type_metadata, is_local_to_unit, global, - ptr::null_mut(), + None, global_align.abi() as u32, ); } @@ -1749,10 +1751,10 @@ pub fn create_vtable_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, Size::ZERO.bits(), cx.tcx.data_layout.pointer_align.abi_bits() as u32, DIFlags::FlagArtificial, - ptr::null_mut(), + None, empty_array, 0, - type_metadata, + NonNull::new(type_metadata), name.as_ptr() ); @@ -1771,7 +1773,7 @@ pub fn create_vtable_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, vtable_type, true, vtable, - ptr::null_mut(), + None, 0); } } diff --git a/src/librustc_codegen_llvm/debuginfo/mod.rs b/src/librustc_codegen_llvm/debuginfo/mod.rs index 9671db75baffe..fcabd27332654 100644 --- a/src/librustc_codegen_llvm/debuginfo/mod.rs +++ b/src/librustc_codegen_llvm/debuginfo/mod.rs @@ -39,7 +39,7 @@ use rustc::util::nodemap::{DefIdMap, FxHashMap, FxHashSet}; use libc::c_uint; use std::cell::{Cell, RefCell}; use std::ffi::CString; -use std::ptr; +use std::ptr::NonNull; use syntax_pos::{self, Span, Pos}; use syntax::ast; @@ -290,7 +290,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, cx.sess().opts.optimize != config::OptLevel::No, llfn, template_parameters, - ptr::null_mut()) + None) }; // Initialize fn debug context (including scope map and namespace map) @@ -312,8 +312,8 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, // Return type -- llvm::DIBuilder wants this at index 0 signature.push(match sig.output().sty { - ty::TyTuple(ref tys) if tys.is_empty() => ptr::null_mut(), - _ => type_metadata(cx, sig.output(), syntax_pos::DUMMY_SP) + ty::TyTuple(ref tys) if tys.is_empty() => None, + _ => NonNull::new(type_metadata(cx, sig.output(), syntax_pos::DUMMY_SP)) }); let inputs = if sig.abi == Abi::RustCall { @@ -342,19 +342,20 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, } _ => t }; - type_metadata(cx, t, syntax_pos::DUMMY_SP) + NonNull::new(type_metadata(cx, t, syntax_pos::DUMMY_SP)) })); } else { signature.extend(inputs.iter().map(|t| { - type_metadata(cx, t, syntax_pos::DUMMY_SP) + NonNull::new(type_metadata(cx, t, syntax_pos::DUMMY_SP)) })); } if sig.abi == Abi::RustCall && !sig.inputs().is_empty() { if let ty::TyTuple(args) = sig.inputs()[sig.inputs().len() - 1].sty { signature.extend( - args.iter().map(|argument_type| - type_metadata(cx, argument_type, syntax_pos::DUMMY_SP)) + args.iter().map(|argument_type| { + NonNull::new(type_metadata(cx, argument_type, syntax_pos::DUMMY_SP)) + }) ); } } @@ -398,14 +399,14 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, type_metadata(cx, actual_type, syntax_pos::DUMMY_SP); let name = CString::new(name.as_str().as_bytes()).unwrap(); Some(unsafe { - llvm::LLVMRustDIBuilderCreateTemplateTypeParameter( + NonNull::new(llvm::LLVMRustDIBuilderCreateTemplateTypeParameter( DIB(cx), - ptr::null_mut(), + None, name.as_ptr(), actual_type_metadata, file_metadata, 0, - 0) + 0)) }) } else { None diff --git a/src/librustc_codegen_llvm/debuginfo/namespace.rs b/src/librustc_codegen_llvm/debuginfo/namespace.rs index 51c45de9dc22a..b651f813408a0 100644 --- a/src/librustc_codegen_llvm/debuginfo/namespace.rs +++ b/src/librustc_codegen_llvm/debuginfo/namespace.rs @@ -22,7 +22,7 @@ use rustc::hir::map::DefPathData; use common::CodegenCx; use std::ffi::CString; -use std::ptr; +use std::ptr::NonNull; pub fn mangled_name_of_instance<'a, 'tcx>( cx: &CodegenCx<'a, 'tcx>, @@ -38,11 +38,11 @@ pub fn item_namespace(cx: &CodegenCx, def_id: DefId) -> DIScope { } let def_key = cx.tcx.def_key(def_id); - let parent_scope = def_key.parent.map_or(ptr::null_mut(), |parent| { - item_namespace(cx, DefId { + let parent_scope = def_key.parent.and_then(|parent| { + NonNull::new(item_namespace(cx, DefId { krate: def_id.krate, index: parent - }) + })) }); let namespace_name = match def_key.disambiguated_data.data { diff --git a/src/librustc_codegen_llvm/debuginfo/source_loc.rs b/src/librustc_codegen_llvm/debuginfo/source_loc.rs index 958d09413edfa..1a1462da3dd9c 100644 --- a/src/librustc_codegen_llvm/debuginfo/source_loc.rs +++ b/src/librustc_codegen_llvm/debuginfo/source_loc.rs @@ -15,18 +15,18 @@ use super::metadata::UNKNOWN_COLUMN_NUMBER; use super::FunctionDebugContext; use llvm; -use llvm::debuginfo::DIScope; +use llvm::debuginfo::{DIScope_opaque, DIScope}; use builder::Builder; use libc::c_uint; -use std::ptr; +use std::ptr::NonNull; use syntax_pos::{Span, Pos}; /// Sets the current debug location at the beginning of the span. /// /// Maps to a call to llvm::LLVMSetCurrentDebugLocation(...). pub fn set_source_location( - debug_context: &FunctionDebugContext, bx: &Builder, scope: DIScope, span: Span + debug_context: &FunctionDebugContext, bx: &Builder, scope: Option>, span: Span ) { let function_debug_context = match *debug_context { FunctionDebugContext::DebugInfoDisabled => return, @@ -40,7 +40,7 @@ pub fn set_source_location( let dbg_loc = if function_debug_context.source_locations_enabled.get() { debug!("set_source_location: {}", bx.sess().codemap().span_to_string(span)); let loc = span_start(bx.cx, span); - InternalDebugLocation::new(scope, loc.line, loc.col.to_usize()) + InternalDebugLocation::new(scope.unwrap().as_ptr(), loc.line, loc.col.to_usize()) } else { UnknownLocation }; @@ -93,17 +93,17 @@ pub fn set_debug_location(bx: &Builder, debug_location: InternalDebugLocation) { debug!("setting debug location to {} {}", line, col); unsafe { - llvm::LLVMRustDIBuilderCreateDebugLocation( + NonNull::new(llvm::LLVMRustDIBuilderCreateDebugLocation( debug_context(bx.cx).llcontext, line as c_uint, col_used, scope, - ptr::null_mut()) + None)) } } UnknownLocation => { debug!("clearing debug location "); - ptr::null_mut() + None } }; diff --git a/src/librustc_codegen_llvm/debuginfo/utils.rs b/src/librustc_codegen_llvm/debuginfo/utils.rs index 9d37f99cb2a59..87da33166286f 100644 --- a/src/librustc_codegen_llvm/debuginfo/utils.rs +++ b/src/librustc_codegen_llvm/debuginfo/utils.rs @@ -17,9 +17,10 @@ use rustc::hir::def_id::DefId; use rustc::ty::DefIdTree; use llvm; -use llvm::debuginfo::{DIScope, DIBuilderRef, DIDescriptor, DIArray}; +use llvm::debuginfo::{DIScope, DIBuilderRef, DIDescriptor_opaque, DIArray}; use common::{CodegenCx}; +use std::ptr::NonNull; use syntax_pos::{self, Span}; pub fn is_node_local_to_unit(cx: &CodegenCx, def_id: DefId) -> bool @@ -36,7 +37,7 @@ pub fn is_node_local_to_unit(cx: &CodegenCx, def_id: DefId) -> bool } #[allow(non_snake_case)] -pub fn create_DIArray(builder: DIBuilderRef, arr: &[DIDescriptor]) -> DIArray { +pub fn create_DIArray(builder: DIBuilderRef, arr: &[Option>]) -> DIArray { return unsafe { llvm::LLVMRustDIBuilderGetOrCreateArray(builder, arr.as_ptr(), arr.len() as u32) }; diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs index 14ec81fc6655b..0b5524990e89c 100644 --- a/src/librustc_codegen_llvm/lib.rs +++ b/src/librustc_codegen_llvm/lib.rs @@ -21,6 +21,7 @@ #![feature(box_patterns)] #![feature(box_syntax)] #![feature(custom_attribute)] +#![feature(extern_types)] #![feature(fs_read_write)] #![allow(unused_attributes)] #![feature(libc)] diff --git a/src/librustc_codegen_llvm/llvm/diagnostic.rs b/src/librustc_codegen_llvm/llvm/diagnostic.rs index 0674bccd51e87..99175864b39a0 100644 --- a/src/librustc_codegen_llvm/llvm/diagnostic.rs +++ b/src/librustc_codegen_llvm/llvm/diagnostic.rs @@ -14,7 +14,6 @@ pub use self::OptimizationDiagnosticKind::*; pub use self::Diagnostic::*; use libc::c_uint; -use std::ptr; use super::{DiagnosticInfoRef, TwineRef, ValueRef}; @@ -56,7 +55,7 @@ impl OptimizationDiagnostic { unsafe fn unpack(kind: OptimizationDiagnosticKind, di: DiagnosticInfoRef) -> OptimizationDiagnostic { - let mut function = ptr::null_mut(); + let mut function = 0 as *mut _; let mut line = 0; let mut column = 0; @@ -105,8 +104,8 @@ impl InlineAsmDiagnostic { let mut opt = InlineAsmDiagnostic { cookie: 0, - message: ptr::null_mut(), - instruction: ptr::null_mut(), + message: 0 as *mut _, + instruction: 0 as *mut _, }; super::LLVMRustUnpackInlineAsmDiagnostic(di, diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index afd1070a77ed7..6e61b327f1d79 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -15,15 +15,17 @@ // https://reviews.llvm.org/D26769 use super::debuginfo::{ - DIBuilderRef, DIDescriptor, DIFile, DILexicalBlock, DISubprogram, DIType, - DIBasicType, DIDerivedType, DICompositeType, DIScope, DIVariable, - DIGlobalVariable, DIArray, DISubrange, DITemplateTypeParameter, DIEnumerator, + DIBuilderRef, DIDescriptor_opaque, DIDescriptor, DIFile, DILexicalBlock, DISubprogram, DIType_opaque, + DIType, DIBasicType, DIDerivedType, DICompositeType, DIScope_opaque, DIScope, DIVariable, + DIGlobalVariable, DIArray_opaque, 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 std::ptr::NonNull; + use super::RustStringRef; pub type Opcode = u32; @@ -348,10 +350,10 @@ pub enum PassKind { } /// LLVMRustThinLTOData -pub enum ThinLTOData {} +extern { pub type ThinLTOData; } /// LLVMRustThinLTOBuffer -pub enum ThinLTOBuffer {} +extern { pub type ThinLTOBuffer; } /// LLVMRustThinLTOModule #[repr(C)] @@ -373,83 +375,59 @@ pub enum ThreadLocalMode { } // Opaque pointer types -#[allow(missing_copy_implementations)] -pub enum Module_opaque {} +extern { pub type Module_opaque; } pub type ModuleRef = *mut Module_opaque; -#[allow(missing_copy_implementations)] -pub enum Context_opaque {} +extern { pub type Context_opaque; } pub type ContextRef = *mut Context_opaque; -#[allow(missing_copy_implementations)] -pub enum Type_opaque {} +extern { pub type Type_opaque; } pub type TypeRef = *mut Type_opaque; -#[allow(missing_copy_implementations)] -pub enum Value_opaque {} +extern { pub type Value_opaque; } pub type ValueRef = *mut Value_opaque; -#[allow(missing_copy_implementations)] -pub enum Metadata_opaque {} +extern { pub type Metadata_opaque; } pub type MetadataRef = *mut Metadata_opaque; -#[allow(missing_copy_implementations)] -pub enum BasicBlock_opaque {} +extern { pub type BasicBlock_opaque; } pub type BasicBlockRef = *mut BasicBlock_opaque; -#[allow(missing_copy_implementations)] -pub enum Builder_opaque {} +extern { pub type Builder_opaque; } pub type BuilderRef = *mut Builder_opaque; -#[allow(missing_copy_implementations)] -pub enum ExecutionEngine_opaque {} +extern { pub type ExecutionEngine_opaque; } pub type ExecutionEngineRef = *mut ExecutionEngine_opaque; -#[allow(missing_copy_implementations)] -pub enum MemoryBuffer_opaque {} +extern { pub type MemoryBuffer_opaque; } pub type MemoryBufferRef = *mut MemoryBuffer_opaque; -#[allow(missing_copy_implementations)] -pub enum PassManager_opaque {} +extern { pub type PassManager_opaque; } pub type PassManagerRef = *mut PassManager_opaque; -#[allow(missing_copy_implementations)] -pub enum PassManagerBuilder_opaque {} +extern { pub type PassManagerBuilder_opaque; } pub type PassManagerBuilderRef = *mut PassManagerBuilder_opaque; -#[allow(missing_copy_implementations)] -pub enum Use_opaque {} +extern { pub type Use_opaque; } pub type UseRef = *mut Use_opaque; -#[allow(missing_copy_implementations)] -pub enum TargetData_opaque {} +extern { pub type TargetData_opaque; } pub type TargetDataRef = *mut TargetData_opaque; -#[allow(missing_copy_implementations)] -pub enum ObjectFile_opaque {} +extern { pub type ObjectFile_opaque; } pub type ObjectFileRef = *mut ObjectFile_opaque; -#[allow(missing_copy_implementations)] -pub enum SectionIterator_opaque {} +extern { pub type SectionIterator_opaque; } pub type SectionIteratorRef = *mut SectionIterator_opaque; -#[allow(missing_copy_implementations)] -pub enum Pass_opaque {} +extern { pub type Pass_opaque; } pub type PassRef = *mut Pass_opaque; -#[allow(missing_copy_implementations)] -pub enum TargetMachine_opaque {} +extern { pub type TargetMachine_opaque; } pub type TargetMachineRef = *mut TargetMachine_opaque; -pub enum Archive_opaque {} +extern { pub type Archive_opaque; } pub type ArchiveRef = *mut Archive_opaque; -pub enum ArchiveIterator_opaque {} +extern { pub type ArchiveIterator_opaque; } pub type ArchiveIteratorRef = *mut ArchiveIterator_opaque; -pub enum ArchiveChild_opaque {} +extern { pub type ArchiveChild_opaque; } pub type ArchiveChildRef = *mut ArchiveChild_opaque; -#[allow(missing_copy_implementations)] -pub enum Twine_opaque {} +extern { pub type Twine_opaque; } pub type TwineRef = *mut Twine_opaque; -#[allow(missing_copy_implementations)] -pub enum DiagnosticInfo_opaque {} +extern { pub type DiagnosticInfo_opaque; } pub type DiagnosticInfoRef = *mut DiagnosticInfo_opaque; -#[allow(missing_copy_implementations)] -pub enum DebugLoc_opaque {} +extern { pub type DebugLoc_opaque; } pub type DebugLocRef = *mut DebugLoc_opaque; -#[allow(missing_copy_implementations)] -pub enum SMDiagnostic_opaque {} +extern { pub type SMDiagnostic_opaque; } pub type SMDiagnosticRef = *mut SMDiagnostic_opaque; -#[allow(missing_copy_implementations)] -pub enum RustArchiveMember_opaque {} +extern { pub type RustArchiveMember_opaque; } pub type RustArchiveMemberRef = *mut RustArchiveMember_opaque; -#[allow(missing_copy_implementations)] -pub enum OperandBundleDef_opaque {} +extern { pub type OperandBundleDef_opaque; } pub type OperandBundleDefRef = *mut OperandBundleDef_opaque; -#[allow(missing_copy_implementations)] -pub enum Linker_opaque {} +extern { pub type Linker_opaque; } pub type LinkerRef = *mut Linker_opaque; pub type DiagnosticHandler = unsafe extern "C" fn(DiagnosticInfoRef, *mut c_void); @@ -457,26 +435,29 @@ pub type InlineAsmDiagHandler = unsafe extern "C" fn(SMDiagnosticRef, *const c_v pub mod debuginfo { - use super::MetadataRef; + use super::Metadata_opaque; - #[allow(missing_copy_implementations)] - pub enum DIBuilder_opaque {} + extern { pub type DIBuilder_opaque; } pub type DIBuilderRef = *mut DIBuilder_opaque; - pub type DIDescriptor = MetadataRef; - pub type DIScope = DIDescriptor; + pub type DIDescriptor_opaque = Metadata_opaque; + pub type DIDescriptor = *mut DIDescriptor_opaque; + pub type DIScope_opaque = DIDescriptor_opaque; + pub type DIScope = *mut DIScope_opaque; 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 DIType_opaque = DIDescriptor_opaque; + pub type DIType = *mut DIType_opaque; 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 DIArray_opaque = DIDescriptor_opaque; + pub type DIArray = *mut DIArray_opaque; pub type DISubrange = DIDescriptor; pub type DIEnumerator = DIDescriptor; pub type DITemplateTypeParameter = DIDescriptor; @@ -512,8 +493,9 @@ pub mod debuginfo { } } -pub enum ModuleBuffer {} +extern { pub type ModuleBuffer; } +#[allow(improper_ctypes)] // TODO remove this (use for NonNull) extern "C" { // Create and destroy contexts. pub fn LLVMRustContextCreate(shouldDiscardNames: bool) -> ContextRef; @@ -793,7 +775,7 @@ extern "C" { pub fn LLVMDisposeBuilder(Builder: BuilderRef); // Metadata - pub fn LLVMSetCurrentDebugLocation(Builder: BuilderRef, L: ValueRef); + pub fn LLVMSetCurrentDebugLocation(Builder: BuilderRef, L: Option>); pub fn LLVMGetCurrentDebugLocation(Builder: BuilderRef) -> ValueRef; pub fn LLVMSetInstDebugLocation(Builder: BuilderRef, Inst: ValueRef); @@ -819,7 +801,7 @@ extern "C" { NumArgs: c_uint, Then: BasicBlockRef, Catch: BasicBlockRef, - Bundle: OperandBundleDefRef, + Bundle: Option>, Name: *const c_char) -> ValueRef; pub fn LLVMBuildLandingPad(B: BuilderRef, @@ -832,14 +814,14 @@ extern "C" { pub fn LLVMBuildUnreachable(B: BuilderRef) -> ValueRef; pub fn LLVMRustBuildCleanupPad(B: BuilderRef, - ParentPad: ValueRef, + ParentPad: Option>, ArgCnt: c_uint, Args: *const ValueRef, Name: *const c_char) -> ValueRef; pub fn LLVMRustBuildCleanupRet(B: BuilderRef, CleanupPad: ValueRef, - UnwindBB: BasicBlockRef) + UnwindBB: Option>) -> ValueRef; pub fn LLVMRustBuildCatchPad(B: BuilderRef, ParentPad: ValueRef, @@ -849,8 +831,8 @@ extern "C" { -> ValueRef; pub fn LLVMRustBuildCatchRet(B: BuilderRef, Pad: ValueRef, BB: BasicBlockRef) -> ValueRef; pub fn LLVMRustBuildCatchSwitch(Builder: BuilderRef, - ParentPad: ValueRef, - BB: BasicBlockRef, + ParentPad: Option>, + BB: Option>, NumHandlers: c_uint, Name: *const c_char) -> ValueRef; @@ -1161,7 +1143,7 @@ extern "C" { Fn: ValueRef, Args: *const ValueRef, NumArgs: c_uint, - Bundle: OperandBundleDefRef, + Bundle: Option>, Name: *const c_char) -> ValueRef; pub fn LLVMBuildSelect(B: BuilderRef, @@ -1433,7 +1415,7 @@ extern "C" { isOptimized: bool, Fn: ValueRef, TParam: DIArray, - Decl: DIDescriptor) + Decl: Option>) -> DISubprogram; pub fn LLVMRustDIBuilderCreateBasicType(Builder: DIBuilderRef, @@ -1451,17 +1433,17 @@ extern "C" { -> DIDerivedType; pub fn LLVMRustDIBuilderCreateStructType(Builder: DIBuilderRef, - Scope: DIDescriptor, + Scope: Option>, Name: *const c_char, File: DIFile, LineNumber: c_uint, SizeInBits: u64, AlignInBits: u32, Flags: DIFlags, - DerivedFrom: DIType, + DerivedFrom: Option>, Elements: DIArray, RunTimeLang: c_uint, - VTableHolder: DIType, + VTableHolder: Option>, UniqueId: *const c_char) -> DICompositeType; @@ -1490,7 +1472,7 @@ extern "C" { -> DILexicalBlock; pub fn LLVMRustDIBuilderCreateStaticVariable(Builder: DIBuilderRef, - Context: DIScope, + Context: Option>, Name: *const c_char, LinkageName: *const c_char, File: DIFile, @@ -1498,7 +1480,7 @@ extern "C" { Ty: DIType, isLocalToUnit: bool, Val: ValueRef, - Decl: DIDescriptor, + Decl: Option>, AlignInBits: u32) -> DIGlobalVariable; @@ -1535,7 +1517,7 @@ extern "C" { -> DISubrange; pub fn LLVMRustDIBuilderGetOrCreateArray(Builder: DIBuilderRef, - Ptr: *const DIDescriptor, + Ptr: *const Option>, Count: c_uint) -> DIArray; @@ -1572,7 +1554,7 @@ extern "C" { SizeInBits: u64, AlignInBits: u32, Flags: DIFlags, - Elements: DIArray, + Elements: Option>, RunTimeLang: c_uint, UniqueId: *const c_char) -> DIType; @@ -1580,7 +1562,7 @@ extern "C" { pub fn LLVMSetUnnamedAddr(GlobalVar: ValueRef, UnnamedAddr: Bool); pub fn LLVMRustDIBuilderCreateTemplateTypeParameter(Builder: DIBuilderRef, - Scope: DIScope, + Scope: Option>, Name: *const c_char, Ty: DIType, File: DIFile, @@ -1590,7 +1572,7 @@ extern "C" { pub fn LLVMRustDIBuilderCreateNameSpace(Builder: DIBuilderRef, - Scope: DIScope, + Scope: Option>, Name: *const c_char, File: DIFile, LineNo: c_uint) @@ -1604,7 +1586,7 @@ extern "C" { Line: c_uint, Column: c_uint, Scope: DIScope, - InlinedAt: MetadataRef) + InlinedAt: Option>) -> ValueRef; pub fn LLVMRustDIBuilderCreateOpDeref() -> i64; pub fn LLVMRustDIBuilderCreateOpPlusUconst() -> i64; @@ -1720,7 +1702,7 @@ extern "C" { -> LLVMRustResult; pub fn LLVMRustArchiveMemberNew(Filename: *const c_char, Name: *const c_char, - Child: ArchiveChildRef) + Child: Option>) -> RustArchiveMemberRef; pub fn LLVMRustArchiveMemberFree(Member: RustArchiveMemberRef); diff --git a/src/librustc_codegen_llvm/mir/mod.rs b/src/librustc_codegen_llvm/mir/mod.rs index 312939408c62c..5fb4cbfb982d5 100644 --- a/src/librustc_codegen_llvm/mir/mod.rs +++ b/src/librustc_codegen_llvm/mir/mod.rs @@ -11,7 +11,7 @@ use common::{C_i32, C_null}; use libc::c_uint; use llvm::{self, ValueRef, BasicBlockRef}; -use llvm::debuginfo::DIScope; +use llvm::debuginfo::DIScope_opaque; use rustc::ty::{self, Ty, TypeFoldable, UpvarSubsts}; use rustc::ty::layout::{LayoutOf, TyLayout}; use rustc::mir::{self, Mir}; @@ -29,6 +29,7 @@ use syntax_pos::{DUMMY_SP, NO_EXPANSION, BytePos, Span}; use syntax::symbol::keywords; use std::iter; +use std::ptr::NonNull; use rustc_data_structures::bitvec::BitVector; use rustc_data_structures::indexed_vec::{IndexVec, Idx}; @@ -121,7 +122,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { debuginfo::set_source_location(&self.debug_context, bx, scope, span); } - pub fn debug_loc(&mut self, source_info: mir::SourceInfo) -> (DIScope, Span) { + pub fn debug_loc(&mut self, source_info: mir::SourceInfo) -> (Option>, Span) { // Bail out if debug info emission is not enabled. match self.debug_context { FunctionDebugContext::DebugInfoDisabled | @@ -161,16 +162,16 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { // corresponding to span's containing source scope. If so, we need to create a DIScope // "extension" into that file. fn scope_metadata_for_loc(&self, scope_id: mir::SourceScope, pos: BytePos) - -> llvm::debuginfo::DIScope { + -> Option> { let scope_metadata = self.scopes[scope_id].scope_metadata; if pos < self.scopes[scope_id].file_start_pos || pos >= self.scopes[scope_id].file_end_pos { let cm = self.cx.sess().codemap(); let defining_crate = self.debug_context.get_ref(DUMMY_SP).defining_crate; - debuginfo::extend_scope_to_file(self.cx, - scope_metadata, + NonNull::new(debuginfo::extend_scope_to_file(self.cx, + scope_metadata.unwrap().as_ptr(), &cm.lookup_char_pos(pos).file, - defining_crate) + defining_crate)) } else { scope_metadata } @@ -280,7 +281,7 @@ pub fn codegen_mir<'a, 'tcx: 'a>( span: decl.source_info.span, scope: decl.visibility_scope, }); - declare_local(&bx, &fx.debug_context, name, layout.ty, scope, + declare_local(&bx, &fx.debug_context, name, layout.ty, scope.unwrap().as_ptr(), VariableAccess::DirectVariable { alloca: place.llval }, VariableKind::LocalVariable, span); } @@ -424,8 +425,8 @@ fn arg_local_refs<'a, 'tcx>(bx: &Builder<'a, 'tcx>, // Get the argument scope, if it exists and if we need it. let arg_scope = scopes[mir::OUTERMOST_SOURCE_SCOPE]; - let arg_scope = if arg_scope.is_valid() && bx.sess().opts.debuginfo == FullDebugInfo { - Some(arg_scope.scope_metadata) + let arg_scope = if bx.sess().opts.debuginfo == FullDebugInfo { + arg_scope.scope_metadata } else { None }; @@ -471,7 +472,7 @@ fn arg_local_refs<'a, 'tcx>(bx: &Builder<'a, 'tcx>, bx, &fx.debug_context, arg_decl.name.unwrap_or(keywords::Invalid.name()), - arg_ty, scope, + arg_ty, scope.as_ptr(), variable_access, VariableKind::ArgumentVariable(arg_index + 1), DUMMY_SP @@ -550,7 +551,7 @@ fn arg_local_refs<'a, 'tcx>(bx: &Builder<'a, 'tcx>, &fx.debug_context, arg_decl.name.unwrap_or(keywords::Invalid.name()), arg.layout.ty, - scope, + scope.as_ptr(), variable_access, VariableKind::ArgumentVariable(arg_index + 1), DUMMY_SP @@ -601,7 +602,7 @@ fn arg_local_refs<'a, 'tcx>(bx: &Builder<'a, 'tcx>, &fx.debug_context, decl.debug_name, ty, - scope, + scope.as_ptr(), variable_access, VariableKind::LocalVariable, DUMMY_SP diff --git a/src/librustc_codegen_llvm/mir/operand.rs b/src/librustc_codegen_llvm/mir/operand.rs index c433df51110e3..78c83f200a517 100644 --- a/src/librustc_codegen_llvm/mir/operand.rs +++ b/src/librustc_codegen_llvm/mir/operand.rs @@ -24,7 +24,6 @@ use value::Value; use type_of::LayoutLlvmExt; use std::fmt; -use std::ptr; use super::{FunctionCx, LocalRef}; use super::constant::scalar_to_llvm; @@ -160,7 +159,7 @@ impl<'a, 'tcx> OperandRef<'tcx> { let projected_ty = self.layout.ty.builtin_deref(true) .unwrap_or_else(|| bug!("deref of non-pointer {:?}", self)).ty; let (llptr, llextra) = match self.val { - OperandValue::Immediate(llptr) => (llptr, ptr::null_mut()), + OperandValue::Immediate(llptr) => (llptr, 0 as *mut _), OperandValue::Pair(llptr, llextra) => (llptr, llextra), OperandValue::Ref(..) => bug!("Deref of by-Ref operand {:?}", self) }; diff --git a/src/librustc_codegen_llvm/mir/place.rs b/src/librustc_codegen_llvm/mir/place.rs index 9abf9077a9577..aff29b06b8f31 100644 --- a/src/librustc_codegen_llvm/mir/place.rs +++ b/src/librustc_codegen_llvm/mir/place.rs @@ -24,8 +24,6 @@ use value::Value; use glue; use mir::constant::const_alloc_to_llvm; -use std::ptr; - use super::{FunctionCx, LocalRef}; use super::operand::{OperandRef, OperandValue}; @@ -51,7 +49,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> { -> PlaceRef<'tcx> { PlaceRef { llval, - llextra: ptr::null_mut(), + llextra: 0 as *mut _, layout, align } @@ -126,7 +124,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> { }; let val = if self.layout.is_llvm_immediate() { - let mut const_llval = ptr::null_mut(); + let mut const_llval = 0 as *mut _; unsafe { let global = llvm::LLVMIsAGlobalVariable(self.llval); if !global.is_null() && llvm::LLVMIsGlobalConstant(global) == llvm::True { @@ -187,7 +185,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> { llextra: if cx.type_has_metadata(field.ty) { self.llextra } else { - ptr::null_mut() + 0 as *mut _ }, layout: field, align, @@ -390,7 +388,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> { -> PlaceRef<'tcx> { PlaceRef { llval: bx.inbounds_gep(self.llval, &[C_usize(bx.cx, 0), llindex]), - llextra: ptr::null_mut(), + llextra: 0 as *mut _, layout: self.layout.field(bx.cx, 0), align: self.align } diff --git a/src/librustc_codegen_llvm/type_.rs b/src/librustc_codegen_llvm/type_.rs index a77acc4f1756f..37157635b2d67 100644 --- a/src/librustc_codegen_llvm/type_.rs +++ b/src/librustc_codegen_llvm/type_.rs @@ -22,7 +22,6 @@ use rustc::ty::layout::{self, Align, Size}; use std::ffi::CString; use std::fmt; use std::mem; -use std::ptr; use libc::c_uint; @@ -103,6 +102,11 @@ impl Type { ty!(llvm::LLVMIntTypeInContext(cx.llcx, num_bits as c_uint)) } + // Creates an integer type with the given number of bits, e.g. i24 + pub fn ix_llcx(llcx: ContextRef, num_bits: u64) -> Type { + ty!(llvm::LLVMIntTypeInContext(llcx, num_bits as c_uint)) + } + pub fn f32(cx: &CodegenCx) -> Type { ty!(llvm::LLVMFloatTypeInContext(cx.llcx)) } @@ -128,12 +132,7 @@ impl Type { } pub fn isize(cx: &CodegenCx) -> Type { - match &cx.tcx.sess.target.target.target_pointer_width[..] { - "16" => Type::i16(cx), - "32" => Type::i32(cx), - "64" => Type::i64(cx), - tws => bug!("Unsupported target word size for int: {}", tws), - } + cx.isize_ty } pub fn c_int(cx: &CodegenCx) -> Type { @@ -241,7 +240,7 @@ impl Type { pub fn func_params(&self) -> Vec { unsafe { let n_args = llvm::LLVMCountParamTypes(self.to_ref()) as usize; - let mut args = vec![Type { rf: ptr::null_mut() }; n_args]; + let mut args = vec![Type { rf: 0 as *mut _ }; n_args]; llvm::LLVMGetParamTypes(self.to_ref(), args.as_mut_ptr() as *mut TypeRef); args From 249d5acaec0b10ee15b21b888977b5445baba42e Mon Sep 17 00:00:00 2001 From: Irina Popa Date: Wed, 27 Jun 2018 17:57:25 +0300 Subject: [PATCH 03/36] rustc_codegen_llvm: use safe references for Context and Module. --- src/librustc_codegen_llvm/allocator.rs | 4 +- src/librustc_codegen_llvm/back/lto.rs | 326 ++++++++-------- src/librustc_codegen_llvm/back/write.rs | 357 +++++++++--------- src/librustc_codegen_llvm/base.rs | 72 ++-- src/librustc_codegen_llvm/common.rs | 6 +- src/librustc_codegen_llvm/context.rs | 110 +++--- .../debuginfo/metadata.rs | 2 +- src/librustc_codegen_llvm/debuginfo/mod.rs | 12 +- src/librustc_codegen_llvm/debuginfo/utils.rs | 2 +- src/librustc_codegen_llvm/lib.rs | 36 +- src/librustc_codegen_llvm/llvm/ffi.rs | 168 ++++----- src/librustc_codegen_llvm/llvm/mod.rs | 2 +- src/librustc_codegen_llvm/type_.rs | 8 +- 13 files changed, 549 insertions(+), 556 deletions(-) diff --git a/src/librustc_codegen_llvm/allocator.rs b/src/librustc_codegen_llvm/allocator.rs index 49cdbf34fa95a..2d401da958b13 100644 --- a/src/librustc_codegen_llvm/allocator.rs +++ b/src/librustc_codegen_llvm/allocator.rs @@ -20,8 +20,8 @@ use ModuleLlvm; use llvm::{self, False, True}; pub(crate) unsafe fn codegen(tcx: TyCtxt, mods: &ModuleLlvm, kind: AllocatorKind) { - let llcx = mods.llcx; - let llmod = mods.llmod; + let llcx = &*mods.llcx; + let llmod = mods.llmod(); let usize = match &tcx.sess.target.target.target_pointer_width[..] { "16" => llvm::LLVMInt16TypeInContext(llcx), "32" => llvm::LLVMInt32TypeInContext(llcx), diff --git a/src/librustc_codegen_llvm/back/lto.rs b/src/librustc_codegen_llvm/back/lto.rs index 93cb9eb976765..fce34710b8143 100644 --- a/src/librustc_codegen_llvm/back/lto.rs +++ b/src/librustc_codegen_llvm/back/lto.rs @@ -14,7 +14,7 @@ use back::write::{ModuleConfig, with_llvm_pmb, CodegenContext}; use back::write; use errors::{FatalError, Handler}; use llvm::archive_ro::ArchiveRO; -use llvm::{ModuleRef, TargetMachineRef, True, False}; +use llvm::{TargetMachineRef, True, False}; use llvm; use rustc::hir::def_id::LOCAL_CRATE; use rustc::middle::exported_symbols::SymbolExportLevel; @@ -73,11 +73,13 @@ impl LtoModuleCodegen { match *self { LtoModuleCodegen::Fat { ref mut module, .. } => { let module = module.take().unwrap(); - let config = cgcx.config(module.kind); - let llmod = module.llvm().unwrap().llmod; - let tm = module.llvm().unwrap().tm; - run_pass_manager(cgcx, tm, llmod, config, false); - timeline.record("fat-done"); + { + let config = cgcx.config(module.kind); + let llmod = module.llvm().unwrap().llmod(); + let tm = &*module.llvm().unwrap().tm; + run_pass_manager(cgcx, tm, llmod, config, false); + timeline.record("fat-done"); + } Ok(module) } LtoModuleCodegen::Thin(ref mut thin) => thin.optimize(cgcx, timeline), @@ -223,66 +225,68 @@ fn fat_lto(cgcx: &CodegenContext, .filter(|&(_, module)| module.kind == ModuleKind::Regular) .map(|(i, module)| { let cost = unsafe { - llvm::LLVMRustModuleCost(module.llvm().unwrap().llmod) + llvm::LLVMRustModuleCost(module.llvm().unwrap().llmod()) }; (cost, i) }) .max() .expect("must be codegen'ing at least one module"); let module = modules.remove(costliest_module); - let llmod = module.llvm().expect("can't lto pre-codegened modules").llmod; - info!("using {:?} as a base module", module.llmod_id); - - // For all other modules we codegened we'll need to link them into our own - // bitcode. All modules were codegened in their own LLVM context, however, - // and we want to move everything to the same LLVM context. Currently the - // way we know of to do that is to serialize them to a string and them parse - // them later. Not great but hey, that's why it's "fat" LTO, right? - for module in modules { - let llvm = module.llvm().expect("can't lto pre-codegened modules"); - let buffer = ModuleBuffer::new(llvm.llmod); - let llmod_id = CString::new(&module.llmod_id[..]).unwrap(); - serialized_modules.push((SerializedModule::Local(buffer), llmod_id)); - } - - // For all serialized bitcode files we parse them and link them in as we did - // above, this is all mostly handled in C++. Like above, though, we don't - // know much about the memory management here so we err on the side of being - // save and persist everything with the original module. let mut serialized_bitcode = Vec::new(); - let mut linker = Linker::new(llmod); - for (bc_decoded, name) in serialized_modules { - info!("linking {:?}", name); - time_ext(cgcx.time_passes, None, &format!("ll link {:?}", name), || { - let data = bc_decoded.data(); - linker.add(&data).map_err(|()| { - let msg = format!("failed to load bc of {:?}", name); - write::llvm_err(&diag_handler, msg) - }) - })?; - timeline.record(&format!("link {:?}", name)); - serialized_bitcode.push(bc_decoded); - } - drop(linker); - cgcx.save_temp_bitcode(&module, "lto.input"); + { + let llmod = module.llvm().expect("can't lto pre-codegened modules").llmod(); + info!("using {:?} as a base module", module.llmod_id); + + // For all other modules we codegened we'll need to link them into our own + // bitcode. All modules were codegened in their own LLVM context, however, + // and we want to move everything to the same LLVM context. Currently the + // way we know of to do that is to serialize them to a string and them parse + // them later. Not great but hey, that's why it's "fat" LTO, right? + for module in modules { + let llvm = module.llvm().expect("can't lto pre-codegened modules"); + let buffer = ModuleBuffer::new(llvm.llmod()); + let llmod_id = CString::new(&module.llmod_id[..]).unwrap(); + serialized_modules.push((SerializedModule::Local(buffer), llmod_id)); + } - // Internalize everything that *isn't* in our whitelist to help strip out - // more modules and such - unsafe { - let ptr = symbol_white_list.as_ptr(); - llvm::LLVMRustRunRestrictionPass(llmod, - ptr as *const *const libc::c_char, - symbol_white_list.len() as libc::size_t); - cgcx.save_temp_bitcode(&module, "lto.after-restriction"); - } + // For all serialized bitcode files we parse them and link them in as we did + // above, this is all mostly handled in C++. Like above, though, we don't + // know much about the memory management here so we err on the side of being + // save and persist everything with the original module. + let mut linker = Linker::new(llmod); + for (bc_decoded, name) in serialized_modules { + info!("linking {:?}", name); + time_ext(cgcx.time_passes, None, &format!("ll link {:?}", name), || { + let data = bc_decoded.data(); + linker.add(&data).map_err(|()| { + let msg = format!("failed to load bc of {:?}", name); + write::llvm_err(&diag_handler, msg) + }) + })?; + timeline.record(&format!("link {:?}", name)); + serialized_bitcode.push(bc_decoded); + } + drop(linker); + cgcx.save_temp_bitcode(&module, "lto.input"); - if cgcx.no_landing_pads { + // Internalize everything that *isn't* in our whitelist to help strip out + // more modules and such unsafe { - llvm::LLVMRustMarkAllFunctionsNounwind(llmod); + let ptr = symbol_white_list.as_ptr(); + llvm::LLVMRustRunRestrictionPass(llmod, + ptr as *const *const libc::c_char, + symbol_white_list.len() as libc::size_t); + cgcx.save_temp_bitcode(&module, "lto.after-restriction"); } - cgcx.save_temp_bitcode(&module, "lto.after-nounwind"); + + if cgcx.no_landing_pads { + unsafe { + llvm::LLVMRustMarkAllFunctionsNounwind(llmod); + } + cgcx.save_temp_bitcode(&module, "lto.after-nounwind"); + } + timeline.record("passes"); } - timeline.record("passes"); Ok(vec![LtoModuleCodegen::Fat { module: Some(module), @@ -293,7 +297,7 @@ fn fat_lto(cgcx: &CodegenContext, struct Linker(llvm::LinkerRef); impl Linker { - fn new(llmod: ModuleRef) -> Linker { + fn new(llmod: &llvm::Module) -> Linker { unsafe { Linker(llvm::LLVMRustLinkerNew(llmod)) } } @@ -371,7 +375,7 @@ fn thin_lto(diag_handler: &Handler, info!("local module: {} - {}", i, module.llmod_id); let llvm = module.llvm().expect("can't lto precodegened module"); let name = CString::new(module.llmod_id.clone()).unwrap(); - let buffer = ThinBuffer::new(llvm.llmod); + let buffer = ThinBuffer::new(llvm.llmod()); thin_modules.push(llvm::ThinLTOModule { identifier: name.as_ptr(), data: buffer.data().as_ptr(), @@ -449,7 +453,7 @@ fn thin_lto(diag_handler: &Handler, fn run_pass_manager(cgcx: &CodegenContext, tm: TargetMachineRef, - llmod: ModuleRef, + llmod: &llvm::Module, config: &ModuleConfig, thin: bool) { // Now we have one massive module inside of llmod. Time to run the @@ -531,7 +535,7 @@ unsafe impl Send for ModuleBuffer {} unsafe impl Sync for ModuleBuffer {} impl ModuleBuffer { - pub fn new(m: ModuleRef) -> ModuleBuffer { + pub fn new(m: &llvm::Module) -> ModuleBuffer { ModuleBuffer(unsafe { llvm::LLVMRustModuleBufferCreate(m) }) @@ -583,7 +587,7 @@ unsafe impl Send for ThinBuffer {} unsafe impl Sync for ThinBuffer {} impl ThinBuffer { - pub fn new(m: ModuleRef) -> ThinBuffer { + pub fn new(m: &llvm::Module) -> ThinBuffer { unsafe { let buffer = llvm::LLVMRustThinLTOBufferCreate(m); ThinBuffer(buffer) @@ -640,19 +644,18 @@ impl ThinModule { // crates but for locally codegened modules we may be able to reuse // that LLVM Context and Module. let llcx = llvm::LLVMRustContextCreate(cgcx.fewer_names); - let llmod = llvm::LLVMRustParseBitcodeForThinLTO( + let llmod_raw = llvm::LLVMRustParseBitcodeForThinLTO( llcx, self.data().as_ptr(), self.data().len(), self.shared.module_names[self.idx].as_ptr(), - ); - if llmod.is_null() { + ).ok_or_else(|| { let msg = "failed to parse bitcode for thin LTO module".to_string(); - return Err(write::llvm_err(&diag_handler, msg)); - } + write::llvm_err(&diag_handler, msg) + })? as *const _; let module = ModuleCodegen { source: ModuleSource::Codegened(ModuleLlvm { - llmod, + llmod_raw, llcx, tm, }), @@ -660,104 +663,107 @@ impl ThinModule { name: self.name().to_string(), kind: ModuleKind::Regular, }; - cgcx.save_temp_bitcode(&module, "thin-lto-input"); - - // Before we do much else find the "main" `DICompileUnit` that we'll be - // using below. If we find more than one though then rustc has changed - // in a way we're not ready for, so generate an ICE by returning - // an error. - let mut cu1 = ptr::null_mut(); - let mut cu2 = ptr::null_mut(); - llvm::LLVMRustThinLTOGetDICompileUnit(llmod, &mut cu1, &mut cu2); - if !cu2.is_null() { - let msg = "multiple source DICompileUnits found".to_string(); - return Err(write::llvm_err(&diag_handler, msg)) - } + { + let llmod = module.llvm().unwrap().llmod(); + cgcx.save_temp_bitcode(&module, "thin-lto-input"); + + // Before we do much else find the "main" `DICompileUnit` that we'll be + // using below. If we find more than one though then rustc has changed + // in a way we're not ready for, so generate an ICE by returning + // an error. + let mut cu1 = ptr::null_mut(); + let mut cu2 = ptr::null_mut(); + llvm::LLVMRustThinLTOGetDICompileUnit(llmod, &mut cu1, &mut cu2); + if !cu2.is_null() { + let msg = "multiple source DICompileUnits found".to_string(); + return Err(write::llvm_err(&diag_handler, msg)) + } - // Like with "fat" LTO, get some better optimizations if landing pads - // are disabled by removing all landing pads. - if cgcx.no_landing_pads { - llvm::LLVMRustMarkAllFunctionsNounwind(llmod); - cgcx.save_temp_bitcode(&module, "thin-lto-after-nounwind"); - timeline.record("nounwind"); - } + // Like with "fat" LTO, get some better optimizations if landing pads + // are disabled by removing all landing pads. + if cgcx.no_landing_pads { + llvm::LLVMRustMarkAllFunctionsNounwind(llmod); + cgcx.save_temp_bitcode(&module, "thin-lto-after-nounwind"); + timeline.record("nounwind"); + } - // Up next comes the per-module local analyses that we do for Thin LTO. - // Each of these functions is basically copied from the LLVM - // implementation and then tailored to suit this implementation. Ideally - // each of these would be supported by upstream LLVM but that's perhaps - // a patch for another day! - // - // You can find some more comments about these functions in the LLVM - // bindings we've got (currently `PassWrapper.cpp`) - if !llvm::LLVMRustPrepareThinLTORename(self.shared.data.0, llmod) { - let msg = "failed to prepare thin LTO module".to_string(); - return Err(write::llvm_err(&diag_handler, msg)) - } - cgcx.save_temp_bitcode(&module, "thin-lto-after-rename"); - timeline.record("rename"); - if !llvm::LLVMRustPrepareThinLTOResolveWeak(self.shared.data.0, llmod) { - let msg = "failed to prepare thin LTO module".to_string(); - return Err(write::llvm_err(&diag_handler, msg)) - } - cgcx.save_temp_bitcode(&module, "thin-lto-after-resolve"); - timeline.record("resolve"); - if !llvm::LLVMRustPrepareThinLTOInternalize(self.shared.data.0, llmod) { - let msg = "failed to prepare thin LTO module".to_string(); - return Err(write::llvm_err(&diag_handler, msg)) - } - cgcx.save_temp_bitcode(&module, "thin-lto-after-internalize"); - timeline.record("internalize"); - if !llvm::LLVMRustPrepareThinLTOImport(self.shared.data.0, llmod) { - let msg = "failed to prepare thin LTO module".to_string(); - return Err(write::llvm_err(&diag_handler, msg)) + // Up next comes the per-module local analyses that we do for Thin LTO. + // Each of these functions is basically copied from the LLVM + // implementation and then tailored to suit this implementation. Ideally + // each of these would be supported by upstream LLVM but that's perhaps + // a patch for another day! + // + // You can find some more comments about these functions in the LLVM + // bindings we've got (currently `PassWrapper.cpp`) + if !llvm::LLVMRustPrepareThinLTORename(self.shared.data.0, llmod) { + let msg = "failed to prepare thin LTO module".to_string(); + return Err(write::llvm_err(&diag_handler, msg)) + } + cgcx.save_temp_bitcode(&module, "thin-lto-after-rename"); + timeline.record("rename"); + if !llvm::LLVMRustPrepareThinLTOResolveWeak(self.shared.data.0, llmod) { + let msg = "failed to prepare thin LTO module".to_string(); + return Err(write::llvm_err(&diag_handler, msg)) + } + cgcx.save_temp_bitcode(&module, "thin-lto-after-resolve"); + timeline.record("resolve"); + if !llvm::LLVMRustPrepareThinLTOInternalize(self.shared.data.0, llmod) { + let msg = "failed to prepare thin LTO module".to_string(); + return Err(write::llvm_err(&diag_handler, msg)) + } + cgcx.save_temp_bitcode(&module, "thin-lto-after-internalize"); + timeline.record("internalize"); + if !llvm::LLVMRustPrepareThinLTOImport(self.shared.data.0, llmod) { + let msg = "failed to prepare thin LTO module".to_string(); + return Err(write::llvm_err(&diag_handler, msg)) + } + cgcx.save_temp_bitcode(&module, "thin-lto-after-import"); + timeline.record("import"); + + // Ok now this is a bit unfortunate. This is also something you won't + // find upstream in LLVM's ThinLTO passes! This is a hack for now to + // work around bugs in LLVM. + // + // First discovered in #45511 it was found that as part of ThinLTO + // importing passes LLVM will import `DICompileUnit` metadata + // information across modules. This means that we'll be working with one + // LLVM module that has multiple `DICompileUnit` instances in it (a + // bunch of `llvm.dbg.cu` members). Unfortunately there's a number of + // bugs in LLVM's backend which generates invalid DWARF in a situation + // like this: + // + // https://bugs.llvm.org/show_bug.cgi?id=35212 + // https://bugs.llvm.org/show_bug.cgi?id=35562 + // + // While the first bug there is fixed the second ended up causing #46346 + // which was basically a resurgence of #45511 after LLVM's bug 35212 was + // fixed. + // + // This function below is a huge hack around this problem. The function + // below is defined in `PassWrapper.cpp` and will basically "merge" + // all `DICompileUnit` instances in a module. Basically it'll take all + // the objects, rewrite all pointers of `DISubprogram` to point to the + // first `DICompileUnit`, and then delete all the other units. + // + // This is probably mangling to the debug info slightly (but hopefully + // not too much) but for now at least gets LLVM to emit valid DWARF (or + // so it appears). Hopefully we can remove this once upstream bugs are + // fixed in LLVM. + llvm::LLVMRustThinLTOPatchDICompileUnit(llmod, cu1); + cgcx.save_temp_bitcode(&module, "thin-lto-after-patch"); + timeline.record("patch"); + + // Alright now that we've done everything related to the ThinLTO + // analysis it's time to run some optimizations! Here we use the same + // `run_pass_manager` as the "fat" LTO above except that we tell it to + // populate a thin-specific pass manager, which presumably LLVM treats a + // little differently. + info!("running thin lto passes over {}", module.name); + let config = cgcx.config(module.kind); + run_pass_manager(cgcx, module.llvm().unwrap().tm, llmod, config, true); + cgcx.save_temp_bitcode(&module, "thin-lto-after-pm"); + timeline.record("thin-done"); } - cgcx.save_temp_bitcode(&module, "thin-lto-after-import"); - timeline.record("import"); - - // Ok now this is a bit unfortunate. This is also something you won't - // find upstream in LLVM's ThinLTO passes! This is a hack for now to - // work around bugs in LLVM. - // - // First discovered in #45511 it was found that as part of ThinLTO - // importing passes LLVM will import `DICompileUnit` metadata - // information across modules. This means that we'll be working with one - // LLVM module that has multiple `DICompileUnit` instances in it (a - // bunch of `llvm.dbg.cu` members). Unfortunately there's a number of - // bugs in LLVM's backend which generates invalid DWARF in a situation - // like this: - // - // https://bugs.llvm.org/show_bug.cgi?id=35212 - // https://bugs.llvm.org/show_bug.cgi?id=35562 - // - // While the first bug there is fixed the second ended up causing #46346 - // which was basically a resurgence of #45511 after LLVM's bug 35212 was - // fixed. - // - // This function below is a huge hack around this problem. The function - // below is defined in `PassWrapper.cpp` and will basically "merge" - // all `DICompileUnit` instances in a module. Basically it'll take all - // the objects, rewrite all pointers of `DISubprogram` to point to the - // first `DICompileUnit`, and then delete all the other units. - // - // This is probably mangling to the debug info slightly (but hopefully - // not too much) but for now at least gets LLVM to emit valid DWARF (or - // so it appears). Hopefully we can remove this once upstream bugs are - // fixed in LLVM. - llvm::LLVMRustThinLTOPatchDICompileUnit(llmod, cu1); - cgcx.save_temp_bitcode(&module, "thin-lto-after-patch"); - timeline.record("patch"); - - // Alright now that we've done everything related to the ThinLTO - // analysis it's time to run some optimizations! Here we use the same - // `run_pass_manager` as the "fat" LTO above except that we tell it to - // populate a thin-specific pass manager, which presumably LLVM treats a - // little differently. - info!("running thin lto passes over {}", module.name); - let config = cgcx.config(module.kind); - run_pass_manager(cgcx, tm, llmod, config, true); - cgcx.save_temp_bitcode(&module, "thin-lto-after-pm"); - timeline.record("thin-done"); Ok(module) } diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs index d36142af56c65..f5c2ca22ec856 100644 --- a/src/librustc_codegen_llvm/back/write.rs +++ b/src/librustc_codegen_llvm/back/write.rs @@ -26,8 +26,8 @@ use rustc::session::Session; use rustc::util::nodemap::FxHashMap; use time_graph::{self, TimeGraph, Timeline}; use llvm; -use llvm::{ModuleRef, TargetMachineRef, PassManagerRef, DiagnosticInfoRef}; -use llvm::{SMDiagnosticRef, ContextRef}; +use llvm::{TargetMachineRef, PassManagerRef, DiagnosticInfoRef}; +use llvm::SMDiagnosticRef; use {CodegenResults, ModuleSource, ModuleCodegen, CompiledModule, ModuleKind}; use CrateInfo; use rustc::hir::def_id::{CrateNum, LOCAL_CRATE}; @@ -96,7 +96,7 @@ pub fn write_output_file( handler: &errors::Handler, target: llvm::TargetMachineRef, pm: llvm::PassManagerRef, - m: ModuleRef, + m: &llvm::Module, output: &Path, file_type: llvm::FileType) -> Result<(), FatalError> { unsafe { @@ -130,7 +130,7 @@ fn get_llvm_opt_size(optimize: config::OptLevel) -> llvm::CodeGenOptSize { } } -pub fn create_target_machine(sess: &Session, find_features: bool) -> TargetMachineRef { +pub fn create_target_machine(sess: &Session, find_features: bool) -> &'static mut llvm::TargetMachine { target_machine_factory(sess, find_features)().unwrap_or_else(|err| { llvm_err(sess.diagnostic(), err).raise() }) @@ -140,7 +140,7 @@ pub fn create_target_machine(sess: &Session, find_features: bool) -> TargetMachi // that `is_pie_binary` is false. When we discover LLVM target features // `sess.crate_types` is uninitialized so we cannot access it. pub fn target_machine_factory(sess: &Session, find_features: bool) - -> Arc Result + Send + Sync> + -> Arc Result<&'static mut llvm::TargetMachine, String> + Send + Sync> { let reloc_model = get_reloc_model(sess); @@ -199,12 +199,10 @@ pub fn target_machine_factory(sess: &Session, find_features: bool) ) }; - if tm.is_null() { - Err(format!("Could not create LLVM TargetMachine for triple: {}", - triple.to_str().unwrap())) - } else { - Ok(tm) - } + tm.ok_or_else(|| { + format!("Could not create LLVM TargetMachine for triple: {}", + triple.to_str().unwrap()) + }) }) } @@ -343,7 +341,7 @@ pub struct CodegenContext { regular_module_config: Arc, metadata_module_config: Arc, allocator_module_config: Arc, - pub tm_factory: Arc Result + Send + Sync>, + pub tm_factory: Arc Result<&'static mut llvm::TargetMachine, String> + Send + Sync>, pub msvc_imps_needed: bool, pub target_pointer_width: String, debuginfo: config::DebugInfoLevel, @@ -392,7 +390,7 @@ impl CodegenContext { let cgu = Some(&module.name[..]); let path = self.output_filenames.temp_path_ext(&ext, cgu); let cstr = path2cstr(&path); - let llmod = module.llvm().unwrap().llmod; + let llmod = module.llvm().unwrap().llmod(); llvm::LLVMWriteBitcodeToFile(llmod, cstr.as_ptr()); } } @@ -400,13 +398,13 @@ impl CodegenContext { struct DiagnosticHandlers<'a> { data: *mut (&'a CodegenContext, &'a Handler), - llcx: ContextRef, + llcx: &'a llvm::Context, } impl<'a> DiagnosticHandlers<'a> { fn new(cgcx: &'a CodegenContext, handler: &'a Handler, - llcx: ContextRef) -> DiagnosticHandlers<'a> { + llcx: &'a llvm::Context) -> Self { let data = Box::into_raw(Box::new((cgcx, handler))); unsafe { llvm::LLVMRustSetInlineAsmDiagnosticHandler(llcx, inline_asm_handler, data as *mut _); @@ -495,7 +493,7 @@ unsafe fn optimize(cgcx: &CodegenContext, -> Result<(), FatalError> { let (llmod, llcx, tm) = match module.source { - ModuleSource::Codegened(ref llvm) => (llvm.llmod, llvm.llcx, llvm.tm), + ModuleSource::Codegened(ref llvm) => (llvm.llmod(), &*llvm.llcx, &*llvm.tm), ModuleSource::Preexisting(_) => { bug!("optimize_and_codegen: called with ModuleSource::Preexisting") } @@ -617,192 +615,191 @@ unsafe fn codegen(cgcx: &CodegenContext, -> Result { timeline.record("codegen"); - let (llmod, llcx, tm) = match module.source { - ModuleSource::Codegened(ref llvm) => (llvm.llmod, llvm.llcx, llvm.tm), - ModuleSource::Preexisting(_) => { - bug!("codegen: called with ModuleSource::Preexisting") - } - }; - let module_name = module.name.clone(); - let module_name = Some(&module_name[..]); - let handlers = DiagnosticHandlers::new(cgcx, diag_handler, llcx); - - if cgcx.msvc_imps_needed { - create_msvc_imps(cgcx, llcx, llmod); - } - - // A codegen-specific pass manager is used to generate object - // files for an LLVM module. - // - // Apparently each of these pass managers is a one-shot kind of - // thing, so we create a new one for each type of output. The - // pass manager passed to the closure should be ensured to not - // escape the closure itself, and the manager should only be - // used once. - unsafe fn with_codegen(tm: TargetMachineRef, - llmod: ModuleRef, - no_builtins: bool, - f: F) -> R - where F: FnOnce(PassManagerRef) -> R, { - let cpm = llvm::LLVMCreatePassManager(); - llvm::LLVMRustAddAnalysisPasses(tm, cpm, llmod); - llvm::LLVMRustAddLibraryInfo(cpm, llmod, no_builtins); - f(cpm) - } - - // If we don't have the integrated assembler, then we need to emit asm - // from LLVM and use `gcc` to create the object file. - let asm_to_obj = config.emit_obj && config.no_integrated_as; - - // Change what we write and cleanup based on whether obj files are - // just llvm bitcode. In that case write bitcode, and possibly - // delete the bitcode if it wasn't requested. Don't generate the - // machine code, instead copy the .o file from the .bc - let write_bc = config.emit_bc || config.obj_is_bitcode; - let rm_bc = !config.emit_bc && config.obj_is_bitcode; - let write_obj = config.emit_obj && !config.obj_is_bitcode && !asm_to_obj; - let copy_bc_to_obj = config.emit_obj && config.obj_is_bitcode; - - let bc_out = cgcx.output_filenames.temp_path(OutputType::Bitcode, module_name); - let obj_out = cgcx.output_filenames.temp_path(OutputType::Object, module_name); - - - if write_bc || config.emit_bc_compressed || config.embed_bitcode { - let thin; - let old; - let data = if llvm::LLVMRustThinLTOAvailable() { - thin = ThinBuffer::new(llmod); - thin.data() - } else { - old = ModuleBuffer::new(llmod); - old.data() + let (llmod, llcx, tm) = match module.source { + ModuleSource::Codegened(ref llvm) => (llvm.llmod(), &*llvm.llcx, &*llvm.tm), + ModuleSource::Preexisting(_) => { + bug!("codegen: called with ModuleSource::Preexisting") + } }; - timeline.record("make-bc"); + let module_name = module.name.clone(); + let module_name = Some(&module_name[..]); + let handlers = DiagnosticHandlers::new(cgcx, diag_handler, llcx); - if write_bc { - if let Err(e) = fs::write(&bc_out, data) { - diag_handler.err(&format!("failed to write bytecode: {}", e)); - } - timeline.record("write-bc"); + if cgcx.msvc_imps_needed { + create_msvc_imps(cgcx, llcx, llmod); } - if config.embed_bitcode { - embed_bitcode(cgcx, llcx, llmod, Some(data)); - timeline.record("embed-bc"); - } + // A codegen-specific pass manager is used to generate object + // files for an LLVM module. + // + // Apparently each of these pass managers is a one-shot kind of + // thing, so we create a new one for each type of output. The + // pass manager passed to the closure should be ensured to not + // escape the closure itself, and the manager should only be + // used once. + unsafe fn with_codegen(tm: TargetMachineRef, + llmod: &llvm::Module, + no_builtins: bool, + f: F) -> R + where F: FnOnce(PassManagerRef) -> R, + { + let cpm = llvm::LLVMCreatePassManager(); + llvm::LLVMRustAddAnalysisPasses(tm, cpm, llmod); + llvm::LLVMRustAddLibraryInfo(cpm, llmod, no_builtins); + f(cpm) + } + + // If we don't have the integrated assembler, then we need to emit asm + // from LLVM and use `gcc` to create the object file. + let asm_to_obj = config.emit_obj && config.no_integrated_as; + + // Change what we write and cleanup based on whether obj files are + // just llvm bitcode. In that case write bitcode, and possibly + // delete the bitcode if it wasn't requested. Don't generate the + // machine code, instead copy the .o file from the .bc + let write_bc = config.emit_bc || config.obj_is_bitcode; + let rm_bc = !config.emit_bc && config.obj_is_bitcode; + let write_obj = config.emit_obj && !config.obj_is_bitcode && !asm_to_obj; + let copy_bc_to_obj = config.emit_obj && config.obj_is_bitcode; + + let bc_out = cgcx.output_filenames.temp_path(OutputType::Bitcode, module_name); + let obj_out = cgcx.output_filenames.temp_path(OutputType::Object, module_name); + + + if write_bc || config.emit_bc_compressed || config.embed_bitcode { + let thin; + let old; + let data = if llvm::LLVMRustThinLTOAvailable() { + thin = ThinBuffer::new(llmod); + thin.data() + } else { + old = ModuleBuffer::new(llmod); + old.data() + }; + timeline.record("make-bc"); - if config.emit_bc_compressed { - let dst = bc_out.with_extension(RLIB_BYTECODE_EXTENSION); - let data = bytecode::encode(&module.llmod_id, data); - if let Err(e) = fs::write(&dst, data) { - diag_handler.err(&format!("failed to write bytecode: {}", e)); + if write_bc { + if let Err(e) = fs::write(&bc_out, data) { + diag_handler.err(&format!("failed to write bytecode: {}", e)); + } + timeline.record("write-bc"); } - timeline.record("compress-bc"); - } - } else if config.embed_bitcode_marker { - embed_bitcode(cgcx, llcx, llmod, None); - } - time_ext(config.time_passes, None, &format!("codegen passes [{}]", module_name.unwrap()), - || -> Result<(), FatalError> { - if config.emit_ir { - let out = cgcx.output_filenames.temp_path(OutputType::LlvmAssembly, module_name); - let out = path2cstr(&out); - - extern "C" fn demangle_callback(input_ptr: *const c_char, - input_len: size_t, - output_ptr: *mut c_char, - output_len: size_t) -> size_t { - let input = unsafe { - slice::from_raw_parts(input_ptr as *const u8, input_len as usize) - }; + if config.embed_bitcode { + embed_bitcode(cgcx, llcx, llmod, Some(data)); + timeline.record("embed-bc"); + } - let input = match str::from_utf8(input) { - Ok(s) => s, - Err(_) => return 0, - }; + if config.emit_bc_compressed { + let dst = bc_out.with_extension(RLIB_BYTECODE_EXTENSION); + let data = bytecode::encode(&module.llmod_id, data); + if let Err(e) = fs::write(&dst, data) { + diag_handler.err(&format!("failed to write bytecode: {}", e)); + } + timeline.record("compress-bc"); + } + } else if config.embed_bitcode_marker { + embed_bitcode(cgcx, llcx, llmod, None); + } + + time_ext(config.time_passes, None, &format!("codegen passes [{}]", module_name.unwrap()), + || -> Result<(), FatalError> { + if config.emit_ir { + let out = cgcx.output_filenames.temp_path(OutputType::LlvmAssembly, module_name); + let out = path2cstr(&out); + + extern "C" fn demangle_callback(input_ptr: *const c_char, + input_len: size_t, + output_ptr: *mut c_char, + output_len: size_t) -> size_t { + let input = unsafe { + slice::from_raw_parts(input_ptr as *const u8, input_len as usize) + }; - let output = unsafe { - slice::from_raw_parts_mut(output_ptr as *mut u8, output_len as usize) - }; - let mut cursor = io::Cursor::new(output); + let input = match str::from_utf8(input) { + Ok(s) => s, + Err(_) => return 0, + }; - let demangled = match rustc_demangle::try_demangle(input) { - Ok(d) => d, - Err(_) => return 0, - }; + let output = unsafe { + slice::from_raw_parts_mut(output_ptr as *mut u8, output_len as usize) + }; + let mut cursor = io::Cursor::new(output); + + let demangled = match rustc_demangle::try_demangle(input) { + Ok(d) => d, + Err(_) => return 0, + }; - if let Err(_) = write!(cursor, "{:#}", demangled) { - // Possible only if provided buffer is not big enough - return 0; + if let Err(_) = write!(cursor, "{:#}", demangled) { + // Possible only if provided buffer is not big enough + return 0; + } + + cursor.position() as size_t } - cursor.position() as size_t + with_codegen(tm, llmod, config.no_builtins, |cpm| { + llvm::LLVMRustPrintModule(cpm, llmod, out.as_ptr(), demangle_callback); + llvm::LLVMDisposePassManager(cpm); + }); + timeline.record("ir"); } - with_codegen(tm, llmod, config.no_builtins, |cpm| { - llvm::LLVMRustPrintModule(cpm, llmod, out.as_ptr(), demangle_callback); - llvm::LLVMDisposePassManager(cpm); - }); - timeline.record("ir"); - } + if config.emit_asm || asm_to_obj { + let path = cgcx.output_filenames.temp_path(OutputType::Assembly, module_name); - if config.emit_asm || asm_to_obj { - let path = cgcx.output_filenames.temp_path(OutputType::Assembly, module_name); - - // We can't use the same module for asm and binary output, because that triggers - // various errors like invalid IR or broken binaries, so we might have to clone the - // module to produce the asm output - let llmod = if config.emit_obj { - llvm::LLVMCloneModule(llmod) - } else { - llmod - }; - with_codegen(tm, llmod, config.no_builtins, |cpm| { - write_output_file(diag_handler, tm, cpm, llmod, &path, - llvm::FileType::AssemblyFile) - })?; - if config.emit_obj { - llvm::LLVMDisposeModule(llmod); + // We can't use the same module for asm and binary output, because that triggers + // various errors like invalid IR or broken binaries, so we might have to clone the + // module to produce the asm output + let llmod = if config.emit_obj { + llvm::LLVMCloneModule(llmod) + } else { + llmod + }; + with_codegen(tm, llmod, config.no_builtins, |cpm| { + write_output_file(diag_handler, tm, cpm, llmod, &path, + llvm::FileType::AssemblyFile) + })?; + timeline.record("asm"); } - timeline.record("asm"); - } - if write_obj { - with_codegen(tm, llmod, config.no_builtins, |cpm| { - write_output_file(diag_handler, tm, cpm, llmod, &obj_out, - llvm::FileType::ObjectFile) - })?; - timeline.record("obj"); - } else if asm_to_obj { - let assembly = cgcx.output_filenames.temp_path(OutputType::Assembly, module_name); - run_assembler(cgcx, diag_handler, &assembly, &obj_out); - timeline.record("asm_to_obj"); - - if !config.emit_asm && !cgcx.save_temps { - drop(fs::remove_file(&assembly)); + if write_obj { + with_codegen(tm, llmod, config.no_builtins, |cpm| { + write_output_file(diag_handler, tm, cpm, llmod, &obj_out, + llvm::FileType::ObjectFile) + })?; + timeline.record("obj"); + } else if asm_to_obj { + let assembly = cgcx.output_filenames.temp_path(OutputType::Assembly, module_name); + run_assembler(cgcx, diag_handler, &assembly, &obj_out); + timeline.record("asm_to_obj"); + + if !config.emit_asm && !cgcx.save_temps { + drop(fs::remove_file(&assembly)); + } } - } - Ok(()) - })?; + Ok(()) + })?; - if copy_bc_to_obj { - debug!("copying bitcode {:?} to obj {:?}", bc_out, obj_out); - if let Err(e) = link_or_copy(&bc_out, &obj_out) { - diag_handler.err(&format!("failed to copy bitcode to object file: {}", e)); + if copy_bc_to_obj { + debug!("copying bitcode {:?} to obj {:?}", bc_out, obj_out); + if let Err(e) = link_or_copy(&bc_out, &obj_out) { + diag_handler.err(&format!("failed to copy bitcode to object file: {}", e)); + } } - } - if rm_bc { - debug!("removing_bitcode {:?}", bc_out); - if let Err(e) = fs::remove_file(&bc_out) { - diag_handler.err(&format!("failed to remove bitcode: {}", e)); + if rm_bc { + debug!("removing_bitcode {:?}", bc_out); + if let Err(e) = fs::remove_file(&bc_out) { + diag_handler.err(&format!("failed to remove bitcode: {}", e)); + } } - } - drop(handlers); + drop(handlers); + } Ok(module.into_compiled_module(config.emit_obj, config.emit_bc, config.emit_bc_compressed, @@ -828,8 +825,8 @@ unsafe fn codegen(cgcx: &CodegenContext, /// Basically all of this is us attempting to follow in the footsteps of clang /// on iOS. See #35968 for lots more info. unsafe fn embed_bitcode(cgcx: &CodegenContext, - llcx: ContextRef, - llmod: ModuleRef, + llcx: &llvm::Context, + llmod: &llvm::Module, bitcode: Option<&[u8]>) { let llconst = C_bytes_in_context(llcx, bitcode.unwrap_or(&[])); let llglobal = llvm::LLVMAddGlobal( @@ -2050,7 +2047,7 @@ pub fn run_assembler(cgcx: &CodegenContext, handler: &Handler, assembly: &Path, } } -pub unsafe fn with_llvm_pmb(llmod: ModuleRef, +pub unsafe fn with_llvm_pmb(llmod: &llvm::Module, config: &ModuleConfig, opt_level: llvm::CodeGenOptLevel, prepare_for_thin_lto: bool, @@ -2353,7 +2350,7 @@ fn msvc_imps_needed(tcx: TyCtxt) -> bool { // when using MSVC linker. We do this only for data, as linker can fix up // code references on its own. // See #26591, #27438 -fn create_msvc_imps(cgcx: &CodegenContext, llcx: ContextRef, llmod: ModuleRef) { +fn create_msvc_imps(cgcx: &CodegenContext, llcx: &llvm::Context, llmod: &llvm::Module) { if !cgcx.msvc_imps_needed { return } diff --git a/src/librustc_codegen_llvm/base.rs b/src/librustc_codegen_llvm/base.rs index 223c04f420f3f..c4fb251c5f42c 100644 --- a/src/librustc_codegen_llvm/base.rs +++ b/src/librustc_codegen_llvm/base.rs @@ -30,8 +30,8 @@ use super::ModuleKind; use abi; use back::link; -use back::write::{self, OngoingCodegen, create_target_machine}; -use llvm::{ContextRef, ModuleRef, ValueRef, Vector, get_param}; +use back::write::{self, OngoingCodegen}; +use llvm::{ValueRef, Vector, get_param}; use llvm; use metadata; use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; @@ -59,7 +59,7 @@ use rustc_mir::monomorphize::collector::{self, MonoItemCollectionMode}; use rustc_mir::monomorphize::item::DefPathBasedNames; use common::{self, C_struct_in_context, C_array, val_ty}; use consts; -use context::{self, CodegenCx}; +use context::CodegenCx; use debuginfo; use declare; use meth; @@ -77,7 +77,6 @@ use rustc_data_structures::sync::Lrc; use std::any::Any; use std::ffi::CString; -use std::str; use std::sync::Arc; use std::time::{Instant, Duration}; use std::i32; @@ -609,16 +608,14 @@ fn maybe_create_entry_wrapper(cx: &CodegenCx) { } fn write_metadata<'a, 'gcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>, - llmod_id: &str, + llvm_module: &ModuleLlvm, link_meta: &LinkMeta) - -> (ContextRef, ModuleRef, EncodedMetadata) { + -> EncodedMetadata { use std::io::Write; use flate2::Compression; use flate2::write::DeflateEncoder; - let (metadata_llcx, metadata_llmod) = unsafe { - context::create_context_and_module(tcx.sess, llmod_id) - }; + let (metadata_llcx, metadata_llmod) = (&*llvm_module.llcx, llvm_module.llmod()); #[derive(PartialEq, Eq, PartialOrd, Ord)] enum MetadataKind { @@ -641,14 +638,12 @@ fn write_metadata<'a, 'gcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>, }).max().unwrap_or(MetadataKind::None); if kind == MetadataKind::None { - return (metadata_llcx, - metadata_llmod, - EncodedMetadata::new()); + return EncodedMetadata::new(); } let metadata = tcx.encode_metadata(link_meta); if kind == MetadataKind::Uncompressed { - return (metadata_llcx, metadata_llmod, metadata); + return metadata; } assert!(kind == MetadataKind::Compressed); @@ -676,7 +671,7 @@ fn write_metadata<'a, 'gcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>, let directive = CString::new(directive).unwrap(); llvm::LLVMSetModuleInlineAsm(metadata_llmod, directive.as_ptr()) } - return (metadata_llcx, metadata_llmod, metadata); + return metadata; } pub struct ValueIter { @@ -698,7 +693,7 @@ impl Iterator for ValueIter { } } -pub fn iter_globals(llmod: llvm::ModuleRef) -> ValueIter { +pub fn iter_globals(llmod: &llvm::Module) -> ValueIter { unsafe { ValueIter { cur: llvm::LLVMGetFirstGlobal(llmod), @@ -731,19 +726,15 @@ pub fn codegen_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // Codegen the metadata. let llmod_id = "metadata"; - let (metadata_llcx, metadata_llmod, metadata) = - time(tcx.sess, "write metadata", || { - write_metadata(tcx, llmod_id, &link_meta) - }); + let metadata_llvm_module = ModuleLlvm::new(tcx.sess, llmod_id); + let metadata = time(tcx.sess, "write metadata", || { + write_metadata(tcx, &metadata_llvm_module, &link_meta) + }); let metadata_module = ModuleCodegen { name: link::METADATA_MODULE_NAME.to_string(), llmod_id: llmod_id.to_string(), - source: ModuleSource::Codegened(ModuleLlvm { - llcx: metadata_llcx, - llmod: metadata_llmod, - tm: create_target_machine(tcx.sess, false), - }), + source: ModuleSource::Codegened(metadata_llvm_module), kind: ModuleKind::Metadata, }; @@ -803,13 +794,7 @@ pub fn codegen_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let allocator_module = if let Some(kind) = *tcx.sess.allocator_kind.get() { unsafe { let llmod_id = "allocator"; - let (llcx, llmod) = - context::create_context_and_module(tcx.sess, llmod_id); - let modules = ModuleLlvm { - llmod, - llcx, - tm: create_target_machine(tcx.sess, false), - }; + let modules = ModuleLlvm::new(tcx.sess, llmod_id); time(tcx.sess, "write allocator module", || { allocator::codegen(tcx, &modules, kind) }); @@ -1200,8 +1185,9 @@ fn compile_codegen_unit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, .to_fingerprint().to_hex()); // Instantiate monomorphizations without filling out definitions yet... - let cx = CodegenCx::new(tcx, cgu, &llmod_id); - let module = { + let llvm_module = ModuleLlvm::new(tcx.sess, &llmod_id); + let stats = { + let cx = CodegenCx::new(tcx, cgu, &llvm_module); let mono_items = cx.codegen_unit .items_in_deterministic_order(cx.tcx); for &(mono_item, (linkage, visibility)) in &mono_items { @@ -1248,21 +1234,15 @@ fn compile_codegen_unit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, debuginfo::finalize(&cx); } - let llvm_module = ModuleLlvm { - llcx: cx.llcx, - llmod: cx.llmod, - tm: create_target_machine(cx.sess(), false), - }; - - ModuleCodegen { - name: cgu_name, - source: ModuleSource::Codegened(llvm_module), - kind: ModuleKind::Regular, - llmod_id, - } + cx.stats.into_inner() }; - (cx.into_stats(), module) + (stats, ModuleCodegen { + name: cgu_name, + source: ModuleSource::Codegened(llvm_module), + kind: ModuleKind::Regular, + llmod_id, + }) } } diff --git a/src/librustc_codegen_llvm/common.rs b/src/librustc_codegen_llvm/common.rs index 60bba635a7887..be948442707c1 100644 --- a/src/librustc_codegen_llvm/common.rs +++ b/src/librustc_codegen_llvm/common.rs @@ -13,7 +13,7 @@ //! Code that is useful in various codegen modules. use llvm; -use llvm::{ValueRef, ContextRef, TypeKind}; +use llvm::{ValueRef, TypeKind}; use llvm::{True, False, Bool, OperandBundleDef}; use rustc::hir::def_id::DefId; use rustc::middle::lang_items::LangItem; @@ -225,7 +225,7 @@ pub fn C_struct(cx: &CodegenCx, elts: &[ValueRef], packed: bool) -> ValueRef { C_struct_in_context(cx.llcx, elts, packed) } -pub fn C_struct_in_context(llcx: ContextRef, elts: &[ValueRef], packed: bool) -> ValueRef { +pub fn C_struct_in_context(llcx: &llvm::Context, elts: &[ValueRef], packed: bool) -> ValueRef { unsafe { llvm::LLVMConstStructInContext(llcx, elts.as_ptr(), elts.len() as c_uint, @@ -249,7 +249,7 @@ pub fn C_bytes(cx: &CodegenCx, bytes: &[u8]) -> ValueRef { C_bytes_in_context(cx.llcx, bytes) } -pub fn C_bytes_in_context(llcx: ContextRef, bytes: &[u8]) -> ValueRef { +pub fn C_bytes_in_context(llcx: &llvm::Context, bytes: &[u8]) -> ValueRef { unsafe { let ptr = bytes.as_ptr() as *const c_char; return llvm::LLVMConstStringInContext(llcx, ptr, bytes.len() as c_uint, True); diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs index 130e14c976dee..f91173226c48d 100644 --- a/src/librustc_codegen_llvm/context.rs +++ b/src/librustc_codegen_llvm/context.rs @@ -10,7 +10,7 @@ use common; use llvm; -use llvm::{ContextRef, ModuleRef, ValueRef}; +use llvm::ValueRef; use rustc::dep_graph::DepGraphSafe; use rustc::hir; use rustc::hir::def_id::DefId; @@ -42,16 +42,16 @@ use syntax::symbol::LocalInternedString; use abi::Abi; /// There is one `CodegenCx` per compilation unit. Each one has its own LLVM -/// `ContextRef` so that several compilation units may be optimized in parallel. -/// All other LLVM data structures in the `CodegenCx` are tied to that `ContextRef`. +/// `llvm::Context` so that several compilation units may be optimized in parallel. +/// All other LLVM data structures in the `CodegenCx` are tied to that `llvm::Context`. pub struct CodegenCx<'a, 'tcx: 'a> { pub tcx: TyCtxt<'a, 'tcx, 'tcx>, pub check_overflow: bool, pub use_dll_storage_attrs: bool, pub tls_model: llvm::ThreadLocalMode, - pub llmod: ModuleRef, - pub llcx: ContextRef, + pub llmod: &'a llvm::Module, + pub llcx: &'a llvm::Context, pub stats: RefCell, pub codegen_unit: Arc>, @@ -94,7 +94,7 @@ pub struct CodegenCx<'a, 'tcx: 'a> { pub pointee_infos: RefCell, Size), Option>>, pub isize_ty: Type, - pub dbg_cx: Option>, + pub dbg_cx: Option>, eh_personality: Cell>, eh_unwind_resume: Cell>, @@ -155,8 +155,7 @@ pub fn is_pie_binary(sess: &Session) -> bool { !is_any_library(sess) && get_reloc_model(sess) == llvm::RelocMode::PIC } -pub unsafe fn create_context_and_module(sess: &Session, mod_name: &str) -> (ContextRef, ModuleRef) { - let llcx = llvm::LLVMRustContextCreate(sess.fewer_names()); +pub unsafe fn create_module(sess: &Session, llcx: &'ll llvm::Context, mod_name: &str) -> &'ll llvm::Module { let mod_name = CString::new(mod_name).unwrap(); let llmod = llvm::LLVMModuleCreateWithNameInContext(mod_name.as_ptr(), llcx); @@ -208,13 +207,13 @@ pub unsafe fn create_context_and_module(sess: &Session, mod_name: &str) -> (Cont llvm::LLVMRustSetModulePIELevel(llmod); } - (llcx, llmod) + llmod } impl<'a, 'tcx> CodegenCx<'a, 'tcx> { - pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>, + crate fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>, codegen_unit: Arc>, - llmod_id: &str) + llvm_module: &'a ::ModuleLlvm) -> CodegenCx<'a, 'tcx> { // An interesting part of Windows which MSVC forces our hand on (and // apparently MinGW didn't) is the usage of `dllimport` and `dllexport` @@ -265,55 +264,48 @@ impl<'a, 'tcx> CodegenCx<'a, 'tcx> { let tls_model = get_tls_model(&tcx.sess); - unsafe { - let (llcx, llmod) = create_context_and_module(&tcx.sess, - &llmod_id[..]); - - let dbg_cx = if tcx.sess.opts.debuginfo != NoDebugInfo { - let dctx = debuginfo::CrateDebugContext::new(llmod); - debuginfo::metadata::compile_unit_metadata(tcx, - &codegen_unit.name().as_str(), - &dctx); - Some(dctx) - } else { - None - }; - - let isize_ty = Type::ix_llcx(llcx, tcx.data_layout.pointer_size.bits()); - - CodegenCx { - tcx, - check_overflow, - use_dll_storage_attrs, - tls_model, - llmod, - llcx, - stats: RefCell::new(Stats::default()), - codegen_unit, - instances: RefCell::new(FxHashMap()), - vtables: RefCell::new(FxHashMap()), - const_cstr_cache: RefCell::new(FxHashMap()), - const_unsized: RefCell::new(FxHashMap()), - const_globals: RefCell::new(FxHashMap()), - statics: RefCell::new(FxHashMap()), - statics_to_rauw: RefCell::new(Vec::new()), - used_statics: RefCell::new(Vec::new()), - lltypes: RefCell::new(FxHashMap()), - scalar_lltypes: RefCell::new(FxHashMap()), - pointee_infos: RefCell::new(FxHashMap()), - isize_ty, - dbg_cx, - eh_personality: Cell::new(None), - eh_unwind_resume: Cell::new(None), - rust_try_fn: Cell::new(None), - intrinsics: RefCell::new(FxHashMap()), - local_gen_sym_counter: Cell::new(0), - } - } - } + let (llcx, llmod) = (&*llvm_module.llcx, llvm_module.llmod()); - pub fn into_stats(self) -> Stats { - self.stats.into_inner() + let dbg_cx = if tcx.sess.opts.debuginfo != NoDebugInfo { + let dctx = debuginfo::CrateDebugContext::new(llmod); + debuginfo::metadata::compile_unit_metadata(tcx, + &codegen_unit.name().as_str(), + &dctx); + Some(dctx) + } else { + None + }; + + let isize_ty = Type::ix_llcx(llcx, tcx.data_layout.pointer_size.bits()); + + CodegenCx { + tcx, + check_overflow, + use_dll_storage_attrs, + tls_model, + llmod, + llcx, + stats: RefCell::new(Stats::default()), + codegen_unit, + instances: RefCell::new(FxHashMap()), + vtables: RefCell::new(FxHashMap()), + const_cstr_cache: RefCell::new(FxHashMap()), + const_unsized: RefCell::new(FxHashMap()), + const_globals: RefCell::new(FxHashMap()), + statics: RefCell::new(FxHashMap()), + statics_to_rauw: RefCell::new(Vec::new()), + used_statics: RefCell::new(Vec::new()), + lltypes: RefCell::new(FxHashMap()), + scalar_lltypes: RefCell::new(FxHashMap()), + pointee_infos: RefCell::new(FxHashMap()), + isize_ty, + dbg_cx, + eh_personality: Cell::new(None), + eh_unwind_resume: Cell::new(None), + rust_try_fn: Cell::new(None), + intrinsics: RefCell::new(FxHashMap()), + local_gen_sym_counter: Cell::new(0), + } } } diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs index 59c14a6910ba2..e7a6dc4522214 100644 --- a/src/librustc_codegen_llvm/debuginfo/metadata.rs +++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs @@ -862,7 +862,7 @@ pub fn compile_unit_metadata(tcx: TyCtxt, return unit_metadata; }; - fn path_to_mdstring(llcx: llvm::ContextRef, path: &Path) -> llvm::ValueRef { + fn path_to_mdstring(llcx: &llvm::Context, path: &Path) -> llvm::ValueRef { let path_str = path2cstr(path); unsafe { llvm::LLVMMDStringInContext(llcx, diff --git a/src/librustc_codegen_llvm/debuginfo/mod.rs b/src/librustc_codegen_llvm/debuginfo/mod.rs index fcabd27332654..d4b5110603369 100644 --- a/src/librustc_codegen_llvm/debuginfo/mod.rs +++ b/src/librustc_codegen_llvm/debuginfo/mod.rs @@ -21,7 +21,7 @@ use self::metadata::{type_metadata, file_metadata, TypeMap}; use self::source_loc::InternalDebugLocation::{self, UnknownLocation}; use llvm; -use llvm::{ModuleRef, ContextRef, ValueRef}; +use llvm::ValueRef; use llvm::debuginfo::{DIFile, DIType, DIScope, DIBuilderRef, DISubprogram, DIArray, DIFlags}; use rustc::hir::CodegenFnAttrFlags; use rustc::hir::def_id::{DefId, CrateNum}; @@ -67,9 +67,9 @@ const DW_TAG_auto_variable: c_uint = 0x100; const DW_TAG_arg_variable: c_uint = 0x101; /// A context object for maintaining all state needed by the debuginfo module. -pub struct CrateDebugContext<'tcx> { - llcontext: ContextRef, - llmod: ModuleRef, +pub struct CrateDebugContext<'a, 'tcx> { + llcontext: &'a llvm::Context, + llmod: &'a llvm::Module, builder: DIBuilderRef, created_files: RefCell>, created_enum_disr_types: RefCell>, @@ -82,8 +82,8 @@ pub struct CrateDebugContext<'tcx> { composite_types_completed: RefCell>, } -impl<'tcx> CrateDebugContext<'tcx> { - pub fn new(llmod: ModuleRef) -> CrateDebugContext<'tcx> { +impl<'a, 'tcx> CrateDebugContext<'a, 'tcx> { + pub fn new(llmod: &'a llvm::Module) -> Self { debug!("CrateDebugContext::new"); let builder = unsafe { llvm::LLVMRustDIBuilderCreate(llmod) }; // DIBuilder inherits context from the module, so we'd better use the same one diff --git a/src/librustc_codegen_llvm/debuginfo/utils.rs b/src/librustc_codegen_llvm/debuginfo/utils.rs index 87da33166286f..85cddb0a580a5 100644 --- a/src/librustc_codegen_llvm/debuginfo/utils.rs +++ b/src/librustc_codegen_llvm/debuginfo/utils.rs @@ -50,7 +50,7 @@ pub fn span_start(cx: &CodegenCx, span: Span) -> syntax_pos::Loc { #[inline] pub fn debug_context<'a, 'tcx>(cx: &'a CodegenCx<'a, 'tcx>) - -> &'a CrateDebugContext<'tcx> { + -> &'a CrateDebugContext<'a, 'tcx> { cx.dbg_cx.as_ref().unwrap() } diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs index 0b5524990e89c..724a2e3e65f42 100644 --- a/src/librustc_codegen_llvm/lib.rs +++ b/src/librustc_codegen_llvm/lib.rs @@ -20,9 +20,11 @@ #![feature(box_patterns)] #![feature(box_syntax)] +#![feature(crate_visibility_modifier)] #![feature(custom_attribute)] #![feature(extern_types)] #![feature(fs_read_write)] +#![feature(in_band_lifetimes)] #![allow(unused_attributes)] #![feature(libc)] #![feature(quote)] @@ -34,6 +36,7 @@ #![feature(link_args)] #![feature(static_nobundle)] +use back::write::create_target_machine; use rustc::dep_graph::WorkProduct; use syntax_pos::symbol::Symbol; @@ -340,22 +343,41 @@ enum ModuleSource { Codegened(ModuleLlvm), } -#[derive(Debug)] struct ModuleLlvm { - llcx: llvm::ContextRef, - llmod: llvm::ModuleRef, - tm: llvm::TargetMachineRef, + llcx: &'static mut llvm::Context, + llmod_raw: *const llvm::Module, + tm: &'static mut llvm::TargetMachine, } unsafe impl Send for ModuleLlvm { } unsafe impl Sync for ModuleLlvm { } +impl ModuleLlvm { + fn new(sess: &Session, mod_name: &str) -> Self { + unsafe { + let llcx = llvm::LLVMRustContextCreate(sess.fewer_names()); + let llmod_raw = context::create_module(sess, llcx, mod_name) as *const _; + + ModuleLlvm { + llmod_raw, + llcx, + tm: create_target_machine(sess, false), + } + } + } + + fn llmod(&self) -> &llvm::Module { + unsafe { + &*self.llmod_raw + } + } +} + impl Drop for ModuleLlvm { fn drop(&mut self) { unsafe { - llvm::LLVMDisposeModule(self.llmod); - llvm::LLVMContextDispose(self.llcx); - llvm::LLVMRustDisposeTargetMachine(self.tm); + llvm::LLVMContextDispose(&mut *(self.llcx as *mut _)); + llvm::LLVMRustDisposeTargetMachine(&mut *(self.tm as *mut _)); } } } diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index 6e61b327f1d79..9d94869dab06e 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -375,10 +375,8 @@ pub enum ThreadLocalMode { } // Opaque pointer types -extern { pub type Module_opaque; } -pub type ModuleRef = *mut Module_opaque; -extern { pub type Context_opaque; } -pub type ContextRef = *mut Context_opaque; +extern { pub type Module; } +extern { pub type Context; } extern { pub type Type_opaque; } pub type TypeRef = *mut Type_opaque; extern { pub type Value_opaque; } @@ -407,8 +405,8 @@ extern { pub type SectionIterator_opaque; } pub type SectionIteratorRef = *mut SectionIterator_opaque; extern { pub type Pass_opaque; } pub type PassRef = *mut Pass_opaque; -extern { pub type TargetMachine_opaque; } -pub type TargetMachineRef = *mut TargetMachine_opaque; +extern { pub type TargetMachine; } +pub type TargetMachineRef = *const TargetMachine; extern { pub type Archive_opaque; } pub type ArchiveRef = *mut Archive_opaque; extern { pub type ArchiveIterator_opaque; } @@ -498,43 +496,42 @@ extern { pub type ModuleBuffer; } #[allow(improper_ctypes)] // TODO remove this (use for NonNull) 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; + pub fn LLVMRustContextCreate(shouldDiscardNames: bool) -> &'static mut Context; + pub fn LLVMContextDispose(C: &'static mut Context); + pub fn LLVMGetMDKindIDInContext(C: &Context, 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); + // Create modules. + pub fn LLVMModuleCreateWithNameInContext(ModuleID: *const c_char, C: &Context) -> &Module; + pub fn LLVMGetModuleContext(M: &Module) -> &Context; + pub fn LLVMCloneModule(M: &Module) -> &Module; /// Data layout. See Module::getDataLayout. - pub fn LLVMGetDataLayout(M: ModuleRef) -> *const c_char; - pub fn LLVMSetDataLayout(M: ModuleRef, Triple: *const c_char); + pub fn LLVMGetDataLayout(M: &Module) -> *const c_char; + pub fn LLVMSetDataLayout(M: &Module, Triple: *const c_char); /// See Module::dump. - pub fn LLVMDumpModule(M: ModuleRef); + pub fn LLVMDumpModule(M: &Module); /// See Module::setModuleInlineAsm. - pub fn LLVMSetModuleInlineAsm(M: ModuleRef, Asm: *const c_char); - pub fn LLVMRustAppendModuleInlineAsm(M: ModuleRef, Asm: *const c_char); + pub fn LLVMSetModuleInlineAsm(M: &Module, Asm: *const c_char); + pub fn LLVMRustAppendModuleInlineAsm(M: &Module, 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 LLVMInt1TypeInContext(C: &Context) -> TypeRef; + pub fn LLVMInt8TypeInContext(C: &Context) -> TypeRef; + pub fn LLVMInt16TypeInContext(C: &Context) -> TypeRef; + pub fn LLVMInt32TypeInContext(C: &Context) -> TypeRef; + pub fn LLVMInt64TypeInContext(C: &Context) -> TypeRef; + pub fn LLVMIntTypeInContext(C: &Context, 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; + pub fn LLVMFloatTypeInContext(C: &Context) -> TypeRef; + pub fn LLVMDoubleTypeInContext(C: &Context) -> TypeRef; // Operations on function types pub fn LLVMFunctionType(ReturnType: TypeRef, @@ -547,7 +544,7 @@ extern "C" { pub fn LLVMGetParamTypes(FunctionTy: TypeRef, Dest: *mut TypeRef); // Operations on struct types - pub fn LLVMStructTypeInContext(C: ContextRef, + pub fn LLVMStructTypeInContext(C: &Context, ElementTypes: *const TypeRef, ElementCount: c_uint, Packed: Bool) @@ -563,9 +560,9 @@ extern "C" { 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; + pub fn LLVMVoidTypeInContext(C: &Context) -> TypeRef; + pub fn LLVMX86MMXTypeInContext(C: &Context) -> TypeRef; + pub fn LLVMRustMetadataTypeInContext(C: &Context) -> TypeRef; // Operations on all values pub fn LLVMTypeOf(Val: ValueRef) -> TypeRef; @@ -589,9 +586,9 @@ extern "C" { 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); + pub fn LLVMMDStringInContext(C: &Context, Str: *const c_char, SLen: c_uint) -> ValueRef; + pub fn LLVMMDNodeInContext(C: &Context, Vals: *const ValueRef, Count: c_uint) -> ValueRef; + pub fn LLVMAddNamedMetadataOperand(M: &Module, Name: *const c_char, Val: ValueRef); // Operations on scalar constants pub fn LLVMConstInt(IntTy: TypeRef, N: c_ulonglong, SignExtend: Bool) -> ValueRef; @@ -604,12 +601,12 @@ extern "C" { // Operations on composite constants - pub fn LLVMConstStringInContext(C: ContextRef, + pub fn LLVMConstStringInContext(C: &Context, Str: *const c_char, Length: c_uint, DontNullTerminate: Bool) -> ValueRef; - pub fn LLVMConstStructInContext(C: ContextRef, + pub fn LLVMConstStructInContext(C: &Context, ConstantVals: *const ValueRef, Count: c_uint, Packed: Bool) @@ -679,7 +676,6 @@ extern "C" { // 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); @@ -694,10 +690,10 @@ extern "C" { // 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 LLVMAddGlobal(M: &Module, Ty: TypeRef, Name: *const c_char) -> ValueRef; + pub fn LLVMGetNamedGlobal(M: &Module, Name: *const c_char) -> ValueRef; + pub fn LLVMRustGetOrInsertGlobal(M: &Module, Name: *const c_char, T: TypeRef) -> ValueRef; + pub fn LLVMGetFirstGlobal(M: &Module) -> ValueRef; pub fn LLVMGetNextGlobal(GlobalVar: ValueRef) -> ValueRef; pub fn LLVMDeleteGlobal(GlobalVar: ValueRef); pub fn LLVMGetInitializer(GlobalVar: ValueRef) -> ValueRef; @@ -706,15 +702,15 @@ extern "C" { 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 LLVMRustGetNamedValue(M: &Module, 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 LLVMAddFunction(M: &Module, Name: *const c_char, FunctionTy: TypeRef) -> ValueRef; + pub fn LLVMGetNamedFunction(M: &Module, Name: *const c_char) -> ValueRef; + pub fn LLVMGetFirstFunction(M: &Module) -> ValueRef; pub fn LLVMGetNextFunction(Fn: ValueRef) -> ValueRef; - pub fn LLVMRustGetOrInsertFunction(M: ModuleRef, + pub fn LLVMRustGetOrInsertFunction(M: &Module, Name: *const c_char, FunctionTy: TypeRef) -> ValueRef; @@ -736,7 +732,7 @@ extern "C" { // Operations on basic blocks pub fn LLVMBasicBlockAsValue(BB: BasicBlockRef) -> ValueRef; pub fn LLVMGetBasicBlockParent(BB: BasicBlockRef) -> ValueRef; - pub fn LLVMAppendBasicBlockInContext(C: ContextRef, + pub fn LLVMAppendBasicBlockInContext(C: &Context, Fn: ValueRef, Name: *const c_char) -> BasicBlockRef; @@ -767,7 +763,7 @@ extern "C" { Count: c_uint); // Instruction builders - pub fn LLVMCreateBuilderInContext(C: ContextRef) -> BuilderRef; + pub fn LLVMCreateBuilderInContext(C: &Context) -> BuilderRef; pub fn LLVMPositionBuilder(Builder: BuilderRef, Block: BasicBlockRef, Instr: ValueRef); pub fn LLVMPositionBuilderBefore(Builder: BuilderRef, Instr: ValueRef); pub fn LLVMPositionBuilderAtEnd(Builder: BuilderRef, Block: BasicBlockRef); @@ -1277,7 +1273,7 @@ extern "C" { 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; + pub fn LLVMWriteBitcodeToFile(M: &Module, Path: *const c_char) -> c_int; /// Creates target data from a target layout string. pub fn LLVMCreateTargetData(StringRep: *const c_char) -> TargetDataRef; @@ -1289,13 +1285,13 @@ extern "C" { pub fn LLVMCreatePassManager() -> PassManagerRef; /// Creates a function-by-function pass manager - pub fn LLVMCreateFunctionPassManagerForModule(M: ModuleRef) -> PassManagerRef; + pub fn LLVMCreateFunctionPassManagerForModule(M: &Module) -> 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 LLVMRunPassManager(PM: PassManagerRef, M: &Module) -> Bool; pub fn LLVMInitializePasses(); @@ -1351,7 +1347,7 @@ extern "C" { /// 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 LLVMStructCreateNamed(C: &Context, Name: *const c_char) -> TypeRef; pub fn LLVMStructSetBody(StructTy: TypeRef, ElementTypes: *const TypeRef, @@ -1371,11 +1367,11 @@ extern "C" { pub fn LLVMRustVersionMajor() -> u32; pub fn LLVMRustVersionMinor() -> u32; - pub fn LLVMRustAddModuleFlag(M: ModuleRef, name: *const c_char, value: u32); + pub fn LLVMRustAddModuleFlag(M: &Module, name: *const c_char, value: u32); - pub fn LLVMRustMetadataAsValue(C: ContextRef, MD: MetadataRef) -> ValueRef; + pub fn LLVMRustMetadataAsValue(C: &Context, MD: MetadataRef) -> ValueRef; - pub fn LLVMRustDIBuilderCreate(M: ModuleRef) -> DIBuilderRef; + pub fn LLVMRustDIBuilderCreate(M: &Module) -> DIBuilderRef; pub fn LLVMRustDIBuilderDispose(Builder: DIBuilderRef); @@ -1582,7 +1578,7 @@ extern "C" { TypeArray: DIArray); - pub fn LLVMRustDIBuilderCreateDebugLocation(Context: ContextRef, + pub fn LLVMRustDIBuilderCreateDebugLocation(Context: &Context, Line: c_uint, Column: c_uint, Scope: DIScope, @@ -1618,11 +1614,11 @@ extern "C" { DataSections: bool, TrapUnreachable: bool, Singlethread: bool) - -> TargetMachineRef; - pub fn LLVMRustDisposeTargetMachine(T: TargetMachineRef); - pub fn LLVMRustAddAnalysisPasses(T: TargetMachineRef, PM: PassManagerRef, M: ModuleRef); + -> Option<&'static mut TargetMachine>; + pub fn LLVMRustDisposeTargetMachine(T: &'static mut TargetMachine); + pub fn LLVMRustAddAnalysisPasses(T: TargetMachineRef, PM: PassManagerRef, M: &Module); pub fn LLVMRustAddBuilderLibraryInfo(PMB: PassManagerBuilderRef, - M: ModuleRef, + M: &Module, DisableSimplifyLibCalls: bool); pub fn LLVMRustConfigurePassManagerBuilder(PMB: PassManagerBuilderRef, OptLevel: CodeGenOptLevel, @@ -1633,17 +1629,17 @@ extern "C" { PGOGenPath: *const c_char, PGOUsePath: *const c_char); pub fn LLVMRustAddLibraryInfo(PM: PassManagerRef, - M: ModuleRef, + M: &Module, DisableSimplifyLibCalls: bool); - pub fn LLVMRustRunFunctionPassManager(PM: PassManagerRef, M: ModuleRef); + pub fn LLVMRustRunFunctionPassManager(PM: PassManagerRef, M: &Module); pub fn LLVMRustWriteOutputFile(T: TargetMachineRef, PM: PassManagerRef, - M: ModuleRef, + M: &Module, Output: *const c_char, FileType: FileType) -> LLVMRustResult; pub fn LLVMRustPrintModule(PM: PassManagerRef, - M: ModuleRef, + M: &Module, Output: *const c_char, Demangle: extern fn(*const c_char, size_t, @@ -1651,10 +1647,10 @@ extern "C" { 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 LLVMRustSetNormalizedTarget(M: &Module, 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 LLVMRustRunRestrictionPass(M: &Module, syms: *const *const c_char, len: size_t); + pub fn LLVMRustMarkAllFunctionsNounwind(M: &Module); pub fn LLVMRustOpenArchive(path: *const c_char) -> ArchiveRef; pub fn LLVMRustArchiveIteratorNew(AR: ArchiveRef) -> ArchiveIteratorRef; @@ -1669,7 +1665,7 @@ extern "C" { pub fn LLVMRustWriteTwineToString(T: TwineRef, s: RustStringRef); - pub fn LLVMContextSetDiagnosticHandler(C: ContextRef, + pub fn LLVMContextSetDiagnosticHandler(C: &Context, Handler: DiagnosticHandler, DiagnosticContext: *mut c_void); @@ -1688,7 +1684,7 @@ extern "C" { pub fn LLVMRustWriteDiagnosticInfoToString(DI: DiagnosticInfoRef, s: RustStringRef); pub fn LLVMRustGetDiagInfoKind(DI: DiagnosticInfoRef) -> DiagnosticKind; - pub fn LLVMRustSetInlineAsmDiagnosticHandler(C: ContextRef, + pub fn LLVMRustSetInlineAsmDiagnosticHandler(C: &Context, H: InlineAsmDiagHandler, CX: *mut c_void); @@ -1706,7 +1702,7 @@ extern "C" { -> RustArchiveMemberRef; pub fn LLVMRustArchiveMemberFree(Member: RustArchiveMemberRef); - pub fn LLVMRustSetDataLayoutFromTargetMachine(M: ModuleRef, TM: TargetMachineRef); + pub fn LLVMRustSetDataLayoutFromTargetMachine(M: &Module, TM: TargetMachineRef); pub fn LLVMRustBuildOperandBundleDef(Name: *const c_char, Inputs: *const ValueRef, @@ -1716,21 +1712,21 @@ extern "C" { pub fn LLVMRustPositionBuilderAtStart(B: BuilderRef, BB: BasicBlockRef); - pub fn LLVMRustSetComdat(M: ModuleRef, V: ValueRef, Name: *const c_char); + pub fn LLVMRustSetComdat(M: &Module, 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 LLVMRustSetModulePIELevel(M: &Module); + pub fn LLVMRustModuleBufferCreate(M: &Module) -> *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 LLVMRustModuleCost(M: &Module) -> u64; pub fn LLVMRustThinLTOAvailable() -> bool; pub fn LLVMRustPGOAvailable() -> bool; pub fn LLVMRustWriteThinBitcodeToFile(PMR: PassManagerRef, - M: ModuleRef, + M: &Module, BC: *const c_char) -> bool; - pub fn LLVMRustThinLTOBufferCreate(M: ModuleRef) -> *mut ThinLTOBuffer; + pub fn LLVMRustThinLTOBufferCreate(M: &Module) -> *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; @@ -1742,34 +1738,34 @@ extern "C" { ) -> *mut ThinLTOData; pub fn LLVMRustPrepareThinLTORename( Data: *const ThinLTOData, - Module: ModuleRef, + Module: &Module, ) -> bool; pub fn LLVMRustPrepareThinLTOResolveWeak( Data: *const ThinLTOData, - Module: ModuleRef, + Module: &Module, ) -> bool; pub fn LLVMRustPrepareThinLTOInternalize( Data: *const ThinLTOData, - Module: ModuleRef, + Module: &Module, ) -> bool; pub fn LLVMRustPrepareThinLTOImport( Data: *const ThinLTOData, - Module: ModuleRef, + Module: &Module, ) -> bool; pub fn LLVMRustFreeThinLTOData(Data: *mut ThinLTOData); pub fn LLVMRustParseBitcodeForThinLTO( - Context: ContextRef, + Context: &Context, 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, + ) -> Option<&Module>; + pub fn LLVMGetModuleIdentifier(M: &Module, size: *mut usize) -> *const c_char; + pub fn LLVMRustThinLTOGetDICompileUnit(M: &Module, CU1: *mut *mut c_void, CU2: *mut *mut c_void); - pub fn LLVMRustThinLTOPatchDICompileUnit(M: ModuleRef, CU: *mut c_void); + pub fn LLVMRustThinLTOPatchDICompileUnit(M: &Module, CU: *mut c_void); - pub fn LLVMRustLinkerNew(M: ModuleRef) -> LinkerRef; + pub fn LLVMRustLinkerNew(M: &Module) -> LinkerRef; pub fn LLVMRustLinkerAdd(linker: LinkerRef, bytecode: *const c_char, bytecode_len: usize) -> bool; diff --git a/src/librustc_codegen_llvm/llvm/mod.rs b/src/librustc_codegen_llvm/llvm/mod.rs index b6ff9b17bd933..75f13e8885866 100644 --- a/src/librustc_codegen_llvm/llvm/mod.rs +++ b/src/librustc_codegen_llvm/llvm/mod.rs @@ -127,7 +127,7 @@ pub fn SetFunctionCallConv(fn_: ValueRef, cc: CallConv) { // 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) { +pub fn SetUniqueComdat(llmod: &Module, val: ValueRef) { unsafe { LLVMRustSetComdat(llmod, val, LLVMGetValueName(val)); } diff --git a/src/librustc_codegen_llvm/type_.rs b/src/librustc_codegen_llvm/type_.rs index 37157635b2d67..cb77ce0039756 100644 --- a/src/librustc_codegen_llvm/type_.rs +++ b/src/librustc_codegen_llvm/type_.rs @@ -11,7 +11,7 @@ #![allow(non_upper_case_globals)] use llvm; -use llvm::{ContextRef, TypeRef, Bool, False, True, TypeKind}; +use llvm::{TypeRef, Bool, False, True, TypeKind}; use llvm::{Float, Double, X86_FP80, PPC_FP128, FP128}; use context::CodegenCx; @@ -77,7 +77,7 @@ impl Type { ty!(llvm::LLVMInt8TypeInContext(cx.llcx)) } - pub fn i8_llcx(llcx: ContextRef) -> Type { + pub fn i8_llcx(llcx: &llvm::Context) -> Type { ty!(llvm::LLVMInt8TypeInContext(llcx)) } @@ -103,7 +103,7 @@ impl Type { } // Creates an integer type with the given number of bits, e.g. i24 - pub fn ix_llcx(llcx: ContextRef, num_bits: u64) -> Type { + pub fn ix_llcx(llcx: &llvm::Context, num_bits: u64) -> Type { ty!(llvm::LLVMIntTypeInContext(llcx, num_bits as c_uint)) } @@ -127,7 +127,7 @@ impl Type { Type::i8(cx).ptr_to() } - pub fn i8p_llcx(llcx: ContextRef) -> Type { + pub fn i8p_llcx(llcx: &llvm::Context) -> Type { Type::i8_llcx(llcx).ptr_to() } From d04e66d1144a66198422dd380254e8e943d46a49 Mon Sep 17 00:00:00 2001 From: Irina Popa Date: Mon, 2 Jul 2018 17:52:53 +0300 Subject: [PATCH 04/36] rustc_codegen_llvm: use safe references for Type. --- src/librustc_codegen_llvm/abi.rs | 34 +-- src/librustc_codegen_llvm/asm.rs | 4 +- src/librustc_codegen_llvm/back/write.rs | 6 +- src/librustc_codegen_llvm/base.rs | 68 +++--- src/librustc_codegen_llvm/builder.rs | 124 +++++------ src/librustc_codegen_llvm/common.rs | 47 ++-- src/librustc_codegen_llvm/consts.rs | 14 +- src/librustc_codegen_llvm/context.rs | 36 +-- src/librustc_codegen_llvm/debuginfo/gdb.rs | 2 +- src/librustc_codegen_llvm/debuginfo/mod.rs | 18 +- src/librustc_codegen_llvm/debuginfo/utils.rs | 3 +- src/librustc_codegen_llvm/declare.rs | 12 +- src/librustc_codegen_llvm/glue.rs | 2 +- src/librustc_codegen_llvm/intrinsic.rs | 145 ++++++------ src/librustc_codegen_llvm/llvm/ffi.rs | 163 +++++++------- src/librustc_codegen_llvm/meth.rs | 4 +- src/librustc_codegen_llvm/mir/analyze.rs | 12 +- src/librustc_codegen_llvm/mir/block.rs | 26 +-- src/librustc_codegen_llvm/mir/constant.rs | 14 +- src/librustc_codegen_llvm/mir/mod.rs | 25 ++- src/librustc_codegen_llvm/mir/operand.rs | 26 +-- src/librustc_codegen_llvm/mir/place.rs | 24 +- src/librustc_codegen_llvm/mir/rvalue.rs | 36 +-- src/librustc_codegen_llvm/mir/statement.rs | 6 +- src/librustc_codegen_llvm/type_.rs | 220 ++++++++++--------- src/librustc_codegen_llvm/type_of.rs | 30 +-- 26 files changed, 568 insertions(+), 533 deletions(-) diff --git a/src/librustc_codegen_llvm/abi.rs b/src/librustc_codegen_llvm/abi.rs index f1a6e9913d6bd..1d6214ab74093 100644 --- a/src/librustc_codegen_llvm/abi.rs +++ b/src/librustc_codegen_llvm/abi.rs @@ -103,11 +103,11 @@ impl ArgAttributesExt for ArgAttributes { } pub trait LlvmType { - fn llvm_type(&self, cx: &CodegenCx) -> Type; + fn llvm_type(&self, cx: &CodegenCx<'ll, '_>) -> &'ll Type; } impl LlvmType for Reg { - fn llvm_type(&self, cx: &CodegenCx) -> Type { + fn llvm_type(&self, cx: &CodegenCx<'ll, '_>) -> &'ll Type { match self.kind { RegKind::Integer => Type::ix(cx, self.size.bits()), RegKind::Float => { @@ -118,14 +118,14 @@ impl LlvmType for Reg { } } RegKind::Vector => { - Type::vector(&Type::i8(cx), self.size.bytes()) + Type::vector(Type::i8(cx), self.size.bytes()) } } } } impl LlvmType for CastTarget { - fn llvm_type(&self, cx: &CodegenCx) -> Type { + fn llvm_type(&self, cx: &CodegenCx<'ll, '_>) -> &'ll Type { let rest_ll_unit = self.rest.unit.llvm_type(cx); let (rest_count, rem_bytes) = if self.rest.unit.size.bytes() == 0 { (0, 0) @@ -142,7 +142,7 @@ impl LlvmType for CastTarget { // Simplify to array when all chunks are the same size and type if rem_bytes == 0 { - return Type::array(&rest_ll_unit, rest_count); + return Type::array(rest_ll_unit, rest_count); } } @@ -165,15 +165,15 @@ impl LlvmType for CastTarget { } pub trait ArgTypeExt<'a, 'tcx> { - fn memory_ty(&self, cx: &CodegenCx<'a, 'tcx>) -> Type; - fn store(&self, bx: &Builder<'a, 'tcx>, val: ValueRef, dst: PlaceRef<'tcx>); - fn store_fn_arg(&self, bx: &Builder<'a, 'tcx>, idx: &mut usize, dst: PlaceRef<'tcx>); + fn memory_ty(&self, cx: &CodegenCx<'a, 'tcx>) -> &'a Type; + fn store(&self, bx: &Builder<'a, 'll, 'tcx>, val: ValueRef, dst: PlaceRef<'tcx>); + fn store_fn_arg(&self, bx: &Builder<'a, 'll, 'tcx>, idx: &mut usize, dst: PlaceRef<'tcx>); } impl<'a, 'tcx> ArgTypeExt<'a, 'tcx> for ArgType<'tcx, Ty<'tcx>> { /// Get the LLVM type for a place of the original Rust type of /// this argument/return, i.e. the result of `type_of::type_of`. - fn memory_ty(&self, cx: &CodegenCx<'a, 'tcx>) -> Type { + fn memory_ty(&self, cx: &CodegenCx<'a, 'tcx>) -> &'a Type { self.layout.llvm_type(cx) } @@ -181,7 +181,7 @@ impl<'a, 'tcx> ArgTypeExt<'a, 'tcx> for ArgType<'tcx, Ty<'tcx>> { /// place for the original Rust type of this argument/return. /// Can be used for both storing formal arguments into Rust variables /// or results of call/invoke instructions into their destinations. - fn store(&self, bx: &Builder<'a, 'tcx>, val: ValueRef, dst: PlaceRef<'tcx>) { + fn store(&self, bx: &Builder<'a, 'll, 'tcx>, val: ValueRef, dst: PlaceRef<'tcx>) { if self.is_ignore() { return; } @@ -234,7 +234,7 @@ impl<'a, 'tcx> ArgTypeExt<'a, 'tcx> for ArgType<'tcx, Ty<'tcx>> { } } - fn store_fn_arg(&self, bx: &Builder<'a, 'tcx>, idx: &mut usize, dst: PlaceRef<'tcx>) { + fn store_fn_arg(&self, bx: &Builder<'a, 'll, 'tcx>, idx: &mut usize, dst: PlaceRef<'tcx>) { let mut next = || { let val = llvm::get_param(bx.llfn(), *idx as c_uint); *idx += 1; @@ -270,10 +270,10 @@ pub trait FnTypeExt<'a, 'tcx> { fn adjust_for_abi(&mut self, cx: &CodegenCx<'a, 'tcx>, abi: Abi); - fn llvm_type(&self, cx: &CodegenCx<'a, 'tcx>) -> Type; + fn llvm_type(&self, cx: &CodegenCx<'a, 'tcx>) -> &'a Type; fn llvm_cconv(&self) -> llvm::CallConv; fn apply_attrs_llfn(&self, llfn: ValueRef); - fn apply_attrs_callsite(&self, bx: &Builder<'a, 'tcx>, callsite: ValueRef); + fn apply_attrs_callsite(&self, bx: &Builder<'a, 'll, 'tcx>, callsite: ValueRef); } impl<'a, 'tcx> FnTypeExt<'a, 'tcx> for FnType<'tcx, Ty<'tcx>> { @@ -564,7 +564,7 @@ impl<'a, 'tcx> FnTypeExt<'a, 'tcx> for FnType<'tcx, Ty<'tcx>> { } } - fn llvm_type(&self, cx: &CodegenCx<'a, 'tcx>) -> Type { + fn llvm_type(&self, cx: &CodegenCx<'a, 'tcx>) -> &'a Type { let args_capacity: usize = self.args.iter().map(|arg| if arg.pad.is_some() { 1 } else { 0 } + if let PassMode::Pair(_, _) = arg.mode { 2 } else { 1 } @@ -606,9 +606,9 @@ impl<'a, 'tcx> FnTypeExt<'a, 'tcx> for FnType<'tcx, Ty<'tcx>> { } if self.variadic { - Type::variadic_func(&llargument_tys, &llreturn_ty) + Type::variadic_func(&llargument_tys, llreturn_ty) } else { - Type::func(&llargument_tys, &llreturn_ty) + Type::func(&llargument_tys, llreturn_ty) } } @@ -659,7 +659,7 @@ impl<'a, 'tcx> FnTypeExt<'a, 'tcx> for FnType<'tcx, Ty<'tcx>> { } } - fn apply_attrs_callsite(&self, bx: &Builder<'a, 'tcx>, callsite: ValueRef) { + fn apply_attrs_callsite(&self, bx: &Builder<'a, 'll, 'tcx>, callsite: ValueRef) { let mut i = 0; let mut apply = |attrs: &ArgAttributes| { attrs.apply_callsite(llvm::AttributePlace::Argument(i), callsite); diff --git a/src/librustc_codegen_llvm/asm.rs b/src/librustc_codegen_llvm/asm.rs index 82f068106ff71..c046b98685a77 100644 --- a/src/librustc_codegen_llvm/asm.rs +++ b/src/librustc_codegen_llvm/asm.rs @@ -24,8 +24,8 @@ use syntax::ast::AsmDialect; use libc::{c_uint, c_char}; // Take an inline assembly expression and splat it out via LLVM -pub fn codegen_inline_asm<'a, 'tcx>( - bx: &Builder<'a, 'tcx>, +pub fn codegen_inline_asm( + bx: &Builder<'a, 'll, 'tcx>, ia: &hir::InlineAsm, outputs: Vec>, mut inputs: Vec diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs index f5c2ca22ec856..ce51a3572d837 100644 --- a/src/librustc_codegen_llvm/back/write.rs +++ b/src/librustc_codegen_llvm/back/write.rs @@ -831,7 +831,7 @@ unsafe fn embed_bitcode(cgcx: &CodegenContext, let llconst = C_bytes_in_context(llcx, bitcode.unwrap_or(&[])); let llglobal = llvm::LLVMAddGlobal( llmod, - val_ty(llconst).to_ref(), + val_ty(llconst), "rustc.embedded.module\0".as_ptr() as *const _, ); llvm::LLVMSetInitializer(llglobal, llconst); @@ -851,7 +851,7 @@ unsafe fn embed_bitcode(cgcx: &CodegenContext, let llconst = C_bytes_in_context(llcx, &[]); let llglobal = llvm::LLVMAddGlobal( llmod, - val_ty(llconst).to_ref(), + val_ty(llconst), "rustc.embedded.cmdline\0".as_ptr() as *const _, ); llvm::LLVMSetInitializer(llglobal, llconst); @@ -2380,7 +2380,7 @@ fn create_msvc_imps(cgcx: &CodegenContext, llcx: &llvm::Context, llmod: &llvm::M .collect::>(); for (imp_name, val) in globals { let imp = llvm::LLVMAddGlobal(llmod, - i8p_ty.to_ref(), + i8p_ty, imp_name.as_ptr() as *const _); llvm::LLVMSetInitializer(imp, consts::ptrcast(val, i8p_ty)); llvm::LLVMRustSetLinkage(imp, llvm::Linkage::ExternalLinkage); diff --git a/src/librustc_codegen_llvm/base.rs b/src/librustc_codegen_llvm/base.rs index c4fb251c5f42c..21b22b387c9f3 100644 --- a/src/librustc_codegen_llvm/base.rs +++ b/src/librustc_codegen_llvm/base.rs @@ -19,9 +19,9 @@ //! //! * There's no way to find out the Ty type of a ValueRef. Doing so //! would be "trying to get the eggs out of an omelette" (credit: -//! pcwalton). You can, instead, find out its TypeRef by calling val_ty, -//! but one TypeRef corresponds to many `Ty`s; for instance, tup(int, int, -//! int) and rec(x=int, y=int, z=int) will have the same TypeRef. +//! pcwalton). You can, instead, find out its llvm::Type by calling val_ty, +//! but one llvm::Type corresponds to many `Ty`s; for instance, tup(int, int, +//! int) and rec(x=int, y=int, z=int) will have the same llvm::Type. use super::ModuleLlvm; use super::ModuleSource; @@ -91,14 +91,14 @@ use mir::operand::OperandValue; use rustc_codegen_utils::check_for_rustc_errors_attr; -pub struct StatRecorder<'a, 'tcx: 'a> { - cx: &'a CodegenCx<'a, 'tcx>, +pub struct StatRecorder<'a, 'll: 'a, 'tcx: 'll> { + cx: &'a CodegenCx<'ll, 'tcx>, name: Option, istart: usize, } -impl<'a, 'tcx> StatRecorder<'a, 'tcx> { - pub fn new(cx: &'a CodegenCx<'a, 'tcx>, name: String) -> StatRecorder<'a, 'tcx> { +impl StatRecorder<'a, 'll, 'tcx> { + pub fn new(cx: &'a CodegenCx<'ll, 'tcx>, name: String) -> Self { let istart = cx.stats.borrow().n_llvm_insns; StatRecorder { cx, @@ -108,7 +108,7 @@ impl<'a, 'tcx> StatRecorder<'a, 'tcx> { } } -impl<'a, 'tcx> Drop for StatRecorder<'a, 'tcx> { +impl Drop for StatRecorder<'a, 'll, 'tcx> { fn drop(&mut self) { if self.cx.sess().codegen_stats() { let mut stats = self.cx.stats.borrow_mut(); @@ -155,12 +155,12 @@ pub fn bin_op_to_fcmp_predicate(op: hir::BinOpKind) -> llvm::RealPredicate { } } -pub fn compare_simd_types<'a, 'tcx>( - bx: &Builder<'a, 'tcx>, +pub fn compare_simd_types( + bx: &Builder<'a, 'll, 'tcx>, lhs: ValueRef, rhs: ValueRef, t: Ty<'tcx>, - ret_ty: Type, + ret_ty: &'ll Type, op: hir::BinOpKind ) -> ValueRef { let signed = match t.sty { @@ -216,8 +216,8 @@ pub fn unsized_info<'cx, 'tcx>(cx: &CodegenCx<'cx, 'tcx>, } /// Coerce `src` to `dst_ty`. `src_ty` must be a thin pointer. -pub fn unsize_thin_ptr<'a, 'tcx>( - bx: &Builder<'a, 'tcx>, +pub fn unsize_thin_ptr( + bx: &Builder<'a, 'll, 'tcx>, src: ValueRef, src_ty: Ty<'tcx>, dst_ty: Ty<'tcx> @@ -271,9 +271,11 @@ pub fn unsize_thin_ptr<'a, 'tcx>( /// Coerce `src`, which is a reference to a value of type `src_ty`, /// to a value of type `dst_ty` and store the result in `dst` -pub fn coerce_unsized_into<'a, 'tcx>(bx: &Builder<'a, 'tcx>, - src: PlaceRef<'tcx>, - dst: PlaceRef<'tcx>) { +pub fn coerce_unsized_into( + bx: &Builder<'a, 'll, 'tcx>, + src: PlaceRef<'tcx>, + dst: PlaceRef<'tcx> +) { let src_ty = src.layout.ty; let dst_ty = dst.layout.ty; let coerce_ptr = || { @@ -334,14 +336,14 @@ pub fn cast_shift_expr_rhs( cast_shift_rhs(op, lhs, rhs, |a, b| cx.trunc(a, b), |a, b| cx.zext(a, b)) } -fn cast_shift_rhs(op: hir::BinOpKind, +fn cast_shift_rhs<'ll, F, G>(op: hir::BinOpKind, lhs: ValueRef, rhs: ValueRef, trunc: F, zext: G) -> ValueRef - where F: FnOnce(ValueRef, Type) -> ValueRef, - G: FnOnce(ValueRef, Type) -> ValueRef + where F: FnOnce(ValueRef, &'ll Type) -> ValueRef, + G: FnOnce(ValueRef, &'ll Type) -> ValueRef { // Shifts may have any size int on the rhs if op.is_shift() { @@ -378,7 +380,7 @@ pub fn wants_msvc_seh(sess: &Session) -> bool { sess.target.target.options.is_like_msvc } -pub fn call_assume<'a, 'tcx>(bx: &Builder<'a, 'tcx>, val: ValueRef) { +pub fn call_assume(bx: &Builder<'a, 'll, 'tcx>, val: ValueRef) { let assume_intrinsic = bx.cx.get_intrinsic("llvm.assume"); bx.call(assume_intrinsic, &[val], None); } @@ -430,8 +432,8 @@ pub fn call_memcpy(bx: &Builder, bx.call(memcpy, &[dst_ptr, src_ptr, size, align, volatile], None); } -pub fn memcpy_ty<'a, 'tcx>( - bx: &Builder<'a, 'tcx>, +pub fn memcpy_ty( + bx: &Builder<'a, 'll, 'tcx>, dst: ValueRef, src: ValueRef, layout: TyLayout<'tcx>, @@ -446,12 +448,14 @@ pub fn memcpy_ty<'a, 'tcx>( call_memcpy(bx, dst, src, C_usize(bx.cx, size), align, flags); } -pub fn call_memset<'a, 'tcx>(bx: &Builder<'a, 'tcx>, - ptr: ValueRef, - fill_byte: ValueRef, - size: ValueRef, - align: ValueRef, - volatile: bool) -> ValueRef { +pub fn call_memset( + bx: &Builder<'a, 'll, 'tcx>, + ptr: ValueRef, + fill_byte: ValueRef, + size: ValueRef, + align: ValueRef, + volatile: bool, +) -> ValueRef { let ptr_width = &bx.cx.sess().target.target.target_pointer_width; let intrinsic_key = format!("llvm.memset.p0i8.i{}", ptr_width); let llintrinsicfn = bx.cx.get_intrinsic(&intrinsic_key); @@ -553,7 +557,7 @@ fn maybe_create_entry_wrapper(cx: &CodegenCx) { rust_main: ValueRef, rust_main_def_id: DefId, use_start_lang_item: bool) { - let llfty = Type::func(&[Type::c_int(cx), Type::i8p(cx).ptr_to()], &Type::c_int(cx)); + let llfty = Type::func(&[Type::c_int(cx), Type::i8p(cx).ptr_to()], Type::c_int(cx)); let main_ret_ty = cx.tcx.fn_sig(rust_main_def_id).output(); // Given that `main()` has no arguments, @@ -656,7 +660,7 @@ fn write_metadata<'a, 'gcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>, let name = exported_symbols::metadata_symbol_name(tcx); let buf = CString::new(name).unwrap(); let llglobal = unsafe { - llvm::LLVMAddGlobal(metadata_llmod, val_ty(llconst).to_ref(), buf.as_ptr()) + llvm::LLVMAddGlobal(metadata_llmod, val_ty(llconst), buf.as_ptr()) }; unsafe { llvm::LLVMSetInitializer(llglobal, llconst); @@ -1206,7 +1210,7 @@ fn compile_codegen_unit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // Run replace-all-uses-with for statics that need it for &(old_g, new_g) in cx.statics_to_rauw.borrow().iter() { unsafe { - let bitcast = llvm::LLVMConstPointerCast(new_g, llvm::LLVMTypeOf(old_g)); + let bitcast = llvm::LLVMConstPointerCast(new_g, val_ty(old_g)); llvm::LLVMReplaceAllUsesWith(old_g, bitcast); llvm::LLVMDeleteGlobal(old_g); } @@ -1221,7 +1225,7 @@ fn compile_codegen_unit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, unsafe { let g = llvm::LLVMAddGlobal(cx.llmod, - val_ty(array).to_ref(), + val_ty(array), name.as_ptr()); llvm::LLVMSetInitializer(g, array); llvm::LLVMRustSetLinkage(g, llvm::Linkage::AppendingLinkage); diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index 5f460a14ef987..a8bfc721a9e9e 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -31,12 +31,12 @@ use syntax_pos::Span; // All Builders must have an llfn associated with them #[must_use] -pub struct Builder<'a, 'tcx: 'a> { +pub struct Builder<'a, 'll: 'a, 'tcx: 'll> { pub llbuilder: BuilderRef, - pub cx: &'a CodegenCx<'a, 'tcx>, + pub cx: &'a CodegenCx<'ll, 'tcx>, } -impl<'a, 'tcx> Drop for Builder<'a, 'tcx> { +impl Drop for Builder<'a, 'll, 'tcx> { fn drop(&mut self) { unsafe { llvm::LLVMDisposeBuilder(self.llbuilder); @@ -59,8 +59,8 @@ bitflags! { } } -impl<'a, 'tcx> Builder<'a, 'tcx> { - pub fn new_block<'b>(cx: &'a CodegenCx<'a, 'tcx>, llfn: ValueRef, name: &'b str) -> Self { +impl Builder<'a, 'll, 'tcx> { + pub fn new_block<'b>(cx: &'a CodegenCx<'ll, 'tcx>, llfn: ValueRef, name: &'b str) -> Self { let bx = Builder::with_cx(cx); let llbb = unsafe { let name = CString::new(name).unwrap(); @@ -74,7 +74,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { bx } - pub fn with_cx(cx: &'a CodegenCx<'a, 'tcx>) -> Self { + pub fn with_cx(cx: &'a CodegenCx<'ll, 'tcx>) -> Self { // Create a fresh builder from the crate context. let llbuilder = unsafe { llvm::LLVMCreateBuilderInContext(cx.llcx) @@ -85,7 +85,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } - pub fn build_sibling_block<'b>(&self, name: &'b str) -> Builder<'a, 'tcx> { + pub fn build_sibling_block<'b>(&self, name: &'b str) -> Builder<'a, 'll, 'tcx> { Builder::new_block(self.cx, self.llfn(), name) } @@ -504,7 +504,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } - pub fn alloca(&self, ty: Type, name: &str, align: Align) -> ValueRef { + pub fn alloca(&self, ty: &'ll Type, name: &str, align: Align) -> ValueRef { let bx = Builder::with_cx(self.cx); bx.position_at_start(unsafe { llvm::LLVMGetFirstBasicBlock(self.llfn()) @@ -512,14 +512,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { bx.dynamic_alloca(ty, name, align) } - pub fn dynamic_alloca(&self, ty: Type, name: &str, align: Align) -> ValueRef { + pub fn dynamic_alloca(&self, ty: &'ll Type, name: &str, align: Align) -> ValueRef { self.count_insn("alloca"); unsafe { let alloca = if name.is_empty() { - llvm::LLVMBuildAlloca(self.llbuilder, ty.to_ref(), noname()) + llvm::LLVMBuildAlloca(self.llbuilder, ty, noname()) } else { let name = CString::new(name).unwrap(); - llvm::LLVMBuildAlloca(self.llbuilder, ty.to_ref(), + llvm::LLVMBuildAlloca(self.llbuilder, ty, name.as_ptr()) }; llvm::LLVMSetAlignment(alloca, align.abi() as c_uint); @@ -678,136 +678,136 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } /* Casts */ - pub fn trunc(&self, val: ValueRef, dest_ty: Type) -> ValueRef { + pub fn trunc(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef { self.count_insn("trunc"); unsafe { - llvm::LLVMBuildTrunc(self.llbuilder, val, dest_ty.to_ref(), noname()) + llvm::LLVMBuildTrunc(self.llbuilder, val, dest_ty, noname()) } } - pub fn zext(&self, val: ValueRef, dest_ty: Type) -> ValueRef { + pub fn zext(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef { self.count_insn("zext"); unsafe { - llvm::LLVMBuildZExt(self.llbuilder, val, dest_ty.to_ref(), noname()) + llvm::LLVMBuildZExt(self.llbuilder, val, dest_ty, noname()) } } - pub fn sext(&self, val: ValueRef, dest_ty: Type) -> ValueRef { + pub fn sext(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef { self.count_insn("sext"); unsafe { - llvm::LLVMBuildSExt(self.llbuilder, val, dest_ty.to_ref(), noname()) + llvm::LLVMBuildSExt(self.llbuilder, val, dest_ty, noname()) } } - pub fn fptoui(&self, val: ValueRef, dest_ty: Type) -> ValueRef { + pub fn fptoui(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef { self.count_insn("fptoui"); unsafe { - llvm::LLVMBuildFPToUI(self.llbuilder, val, dest_ty.to_ref(), noname()) + llvm::LLVMBuildFPToUI(self.llbuilder, val, dest_ty, noname()) } } - pub fn fptosi(&self, val: ValueRef, dest_ty: Type) -> ValueRef { + pub fn fptosi(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef { self.count_insn("fptosi"); unsafe { - llvm::LLVMBuildFPToSI(self.llbuilder, val, dest_ty.to_ref(),noname()) + llvm::LLVMBuildFPToSI(self.llbuilder, val, dest_ty,noname()) } } - pub fn uitofp(&self, val: ValueRef, dest_ty: Type) -> ValueRef { + pub fn uitofp(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef { self.count_insn("uitofp"); unsafe { - llvm::LLVMBuildUIToFP(self.llbuilder, val, dest_ty.to_ref(), noname()) + llvm::LLVMBuildUIToFP(self.llbuilder, val, dest_ty, noname()) } } - pub fn sitofp(&self, val: ValueRef, dest_ty: Type) -> ValueRef { + pub fn sitofp(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef { self.count_insn("sitofp"); unsafe { - llvm::LLVMBuildSIToFP(self.llbuilder, val, dest_ty.to_ref(), noname()) + llvm::LLVMBuildSIToFP(self.llbuilder, val, dest_ty, noname()) } } - pub fn fptrunc(&self, val: ValueRef, dest_ty: Type) -> ValueRef { + pub fn fptrunc(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef { self.count_insn("fptrunc"); unsafe { - llvm::LLVMBuildFPTrunc(self.llbuilder, val, dest_ty.to_ref(), noname()) + llvm::LLVMBuildFPTrunc(self.llbuilder, val, dest_ty, noname()) } } - pub fn fpext(&self, val: ValueRef, dest_ty: Type) -> ValueRef { + pub fn fpext(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef { self.count_insn("fpext"); unsafe { - llvm::LLVMBuildFPExt(self.llbuilder, val, dest_ty.to_ref(), noname()) + llvm::LLVMBuildFPExt(self.llbuilder, val, dest_ty, noname()) } } - pub fn ptrtoint(&self, val: ValueRef, dest_ty: Type) -> ValueRef { + pub fn ptrtoint(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef { self.count_insn("ptrtoint"); unsafe { - llvm::LLVMBuildPtrToInt(self.llbuilder, val, dest_ty.to_ref(), noname()) + llvm::LLVMBuildPtrToInt(self.llbuilder, val, dest_ty, noname()) } } - pub fn inttoptr(&self, val: ValueRef, dest_ty: Type) -> ValueRef { + pub fn inttoptr(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef { self.count_insn("inttoptr"); unsafe { - llvm::LLVMBuildIntToPtr(self.llbuilder, val, dest_ty.to_ref(), noname()) + llvm::LLVMBuildIntToPtr(self.llbuilder, val, dest_ty, noname()) } } - pub fn bitcast(&self, val: ValueRef, dest_ty: Type) -> ValueRef { + pub fn bitcast(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef { self.count_insn("bitcast"); unsafe { - llvm::LLVMBuildBitCast(self.llbuilder, val, dest_ty.to_ref(), noname()) + llvm::LLVMBuildBitCast(self.llbuilder, val, dest_ty, noname()) } } - pub fn zext_or_bitcast(&self, val: ValueRef, dest_ty: Type) -> ValueRef { + pub fn zext_or_bitcast(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef { self.count_insn("zextorbitcast"); unsafe { - llvm::LLVMBuildZExtOrBitCast(self.llbuilder, val, dest_ty.to_ref(), noname()) + llvm::LLVMBuildZExtOrBitCast(self.llbuilder, val, dest_ty, noname()) } } - pub fn sext_or_bitcast(&self, val: ValueRef, dest_ty: Type) -> ValueRef { + pub fn sext_or_bitcast(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef { self.count_insn("sextorbitcast"); unsafe { - llvm::LLVMBuildSExtOrBitCast(self.llbuilder, val, dest_ty.to_ref(), noname()) + llvm::LLVMBuildSExtOrBitCast(self.llbuilder, val, dest_ty, noname()) } } - pub fn trunc_or_bitcast(&self, val: ValueRef, dest_ty: Type) -> ValueRef { + pub fn trunc_or_bitcast(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef { self.count_insn("truncorbitcast"); unsafe { - llvm::LLVMBuildTruncOrBitCast(self.llbuilder, val, dest_ty.to_ref(), noname()) + llvm::LLVMBuildTruncOrBitCast(self.llbuilder, val, dest_ty, noname()) } } - pub fn cast(&self, op: Opcode, val: ValueRef, dest_ty: Type) -> ValueRef { + pub fn cast(&self, op: Opcode, val: ValueRef, dest_ty: &'ll Type) -> ValueRef { self.count_insn("cast"); unsafe { - llvm::LLVMBuildCast(self.llbuilder, op, val, dest_ty.to_ref(), noname()) + llvm::LLVMBuildCast(self.llbuilder, op, val, dest_ty, noname()) } } - pub fn pointercast(&self, val: ValueRef, dest_ty: Type) -> ValueRef { + pub fn pointercast(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef { self.count_insn("pointercast"); unsafe { - llvm::LLVMBuildPointerCast(self.llbuilder, val, dest_ty.to_ref(), noname()) + llvm::LLVMBuildPointerCast(self.llbuilder, val, dest_ty, noname()) } } - pub fn intcast(&self, val: ValueRef, dest_ty: Type, is_signed: bool) -> ValueRef { + pub fn intcast(&self, val: ValueRef, dest_ty: &'ll Type, is_signed: bool) -> ValueRef { self.count_insn("intcast"); unsafe { - llvm::LLVMRustBuildIntCast(self.llbuilder, val, dest_ty.to_ref(), is_signed) + llvm::LLVMRustBuildIntCast(self.llbuilder, val, dest_ty, is_signed) } } - pub fn fpcast(&self, val: ValueRef, dest_ty: Type) -> ValueRef { + pub fn fpcast(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef { self.count_insn("fpcast"); unsafe { - llvm::LLVMBuildFPCast(self.llbuilder, val, dest_ty.to_ref(), noname()) + llvm::LLVMBuildFPCast(self.llbuilder, val, dest_ty, noname()) } } @@ -828,14 +828,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } /* Miscellaneous instructions */ - pub fn empty_phi(&self, ty: Type) -> ValueRef { + pub fn empty_phi(&self, ty: &'ll Type) -> ValueRef { self.count_insn("emptyphi"); unsafe { - llvm::LLVMBuildPhi(self.llbuilder, ty.to_ref(), noname()) + llvm::LLVMBuildPhi(self.llbuilder, ty, noname()) } } - pub fn phi(&self, ty: Type, vals: &[ValueRef], bbs: &[BasicBlockRef]) -> ValueRef { + pub fn phi(&self, ty: &'ll Type, vals: &[ValueRef], bbs: &[BasicBlockRef]) -> ValueRef { assert_eq!(vals.len(), bbs.len()); let phi = self.empty_phi(ty); self.count_insn("addincoming"); @@ -865,7 +865,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.count_insn("inlineasm"); let comment_text = CString::new(comment_text).unwrap(); let asm = unsafe { - llvm::LLVMConstInlineAsm(Type::func(&[], &Type::void(self.cx)).to_ref(), + llvm::LLVMConstInlineAsm(Type::func(&[], Type::void(self.cx)), comment_text.as_ptr(), noname(), False, False) }; @@ -874,7 +874,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } pub fn inline_asm_call(&self, asm: *const c_char, cons: *const c_char, - inputs: &[ValueRef], output: Type, + inputs: &[ValueRef], output: &'ll Type, volatile: bool, alignstack: bool, dia: AsmDialect) -> ValueRef { self.count_insn("inlineasm"); @@ -890,10 +890,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { }).collect::>(); debug!("Asm Output Type: {:?}", output); - let fty = Type::func(&argtys[..], &output); + let fty = Type::func(&argtys[..], output); unsafe { let v = llvm::LLVMRustInlineAsm( - fty.to_ref(), asm, cons, volatile, alignstack, dia); + fty, asm, cons, volatile, alignstack, dia); self.call(v, inputs, None) } } @@ -946,10 +946,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } - pub fn va_arg(&self, list: ValueRef, ty: Type) -> ValueRef { + pub fn va_arg(&self, list: ValueRef, ty: &'ll Type) -> ValueRef { self.count_insn("vaarg"); unsafe { - llvm::LLVMBuildVAArg(self.llbuilder, list, ty.to_ref(), noname()) + llvm::LLVMBuildVAArg(self.llbuilder, list, ty, noname()) } } @@ -977,9 +977,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { pub fn vector_splat(&self, num_elts: usize, elt: ValueRef) -> ValueRef { unsafe { let elt_ty = val_ty(elt); - let undef = llvm::LLVMGetUndef(Type::vector(&elt_ty, num_elts as u64).to_ref()); + let undef = llvm::LLVMGetUndef(Type::vector(elt_ty, num_elts as u64)); let vec = self.insert_element(undef, elt, C_i32(self.cx, 0)); - let vec_i32_ty = Type::vector(&Type::i32(self.cx), num_elts as u64); + let vec_i32_ty = Type::vector(Type::i32(self.cx), num_elts as u64); self.shuffle_vector(vec, undef, C_null(vec_i32_ty)) } } @@ -1164,11 +1164,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } - pub fn landing_pad(&self, ty: Type, pers_fn: ValueRef, + pub fn landing_pad(&self, ty: &'ll Type, pers_fn: ValueRef, num_clauses: usize) -> ValueRef { self.count_insn("landingpad"); unsafe { - llvm::LLVMBuildLandingPad(self.llbuilder, ty.to_ref(), pers_fn, + llvm::LLVMBuildLandingPad(self.llbuilder, ty, pers_fn, num_clauses as c_uint, noname()) } } diff --git a/src/librustc_codegen_llvm/common.rs b/src/librustc_codegen_llvm/common.rs index be948442707c1..7b90616416890 100644 --- a/src/librustc_codegen_llvm/common.rs +++ b/src/librustc_codegen_llvm/common.rs @@ -112,41 +112,42 @@ impl Funclet { } } -pub fn val_ty(v: ValueRef) -> Type { +// TODO: use proper lifetime in return type +pub fn val_ty(v: ValueRef) -> &'static Type { unsafe { - Type::from_ref(llvm::LLVMTypeOf(v)) + llvm::LLVMTypeOf(&*v) } } // LLVM constant constructors. -pub fn C_null(t: Type) -> ValueRef { +pub fn C_null(t: &Type) -> ValueRef { unsafe { - llvm::LLVMConstNull(t.to_ref()) + llvm::LLVMConstNull(t) } } -pub fn C_undef(t: Type) -> ValueRef { +pub fn C_undef(t: &Type) -> ValueRef { unsafe { - llvm::LLVMGetUndef(t.to_ref()) + llvm::LLVMGetUndef(t) } } -pub fn C_int(t: Type, i: i64) -> ValueRef { +pub fn C_int(t: &Type, i: i64) -> ValueRef { unsafe { - llvm::LLVMConstInt(t.to_ref(), i as u64, True) + llvm::LLVMConstInt(t, i as u64, True) } } -pub fn C_uint(t: Type, i: u64) -> ValueRef { +pub fn C_uint(t: &Type, i: u64) -> ValueRef { unsafe { - llvm::LLVMConstInt(t.to_ref(), i, False) + llvm::LLVMConstInt(t, i, False) } } -pub fn C_uint_big(t: Type, u: u128) -> ValueRef { +pub fn C_uint_big(t: &Type, u: u128) -> ValueRef { unsafe { let words = [u as u64, (u >> 64) as u64]; - llvm::LLVMConstIntOfArbitraryPrecision(t.to_ref(), 2, words.as_ptr()) + llvm::LLVMConstIntOfArbitraryPrecision(t, 2, words.as_ptr()) } } @@ -233,9 +234,9 @@ pub fn C_struct_in_context(llcx: &llvm::Context, elts: &[ValueRef], packed: bool } } -pub fn C_array(ty: Type, elts: &[ValueRef]) -> ValueRef { +pub fn C_array(ty: &Type, elts: &[ValueRef]) -> ValueRef { unsafe { - return llvm::LLVMConstArray(ty.to_ref(), elts.as_ptr(), elts.len() as c_uint); + return llvm::LLVMConstArray(ty, elts.as_ptr(), elts.len() as c_uint); } } @@ -345,8 +346,8 @@ pub fn langcall(tcx: TyCtxt, // all shifts). For 32- and 64-bit types, this matches the semantics // of Java. (See related discussion on #1877 and #10183.) -pub fn build_unchecked_lshift<'a, 'tcx>( - bx: &Builder<'a, 'tcx>, +pub fn build_unchecked_lshift( + bx: &Builder<'a, 'll, 'tcx>, lhs: ValueRef, rhs: ValueRef ) -> ValueRef { @@ -356,8 +357,8 @@ pub fn build_unchecked_lshift<'a, 'tcx>( bx.shl(lhs, rhs) } -pub fn build_unchecked_rshift<'a, 'tcx>( - bx: &Builder<'a, 'tcx>, lhs_t: Ty<'tcx>, lhs: ValueRef, rhs: ValueRef +pub fn build_unchecked_rshift( + bx: &Builder<'a, 'll, 'tcx>, lhs_t: Ty<'tcx>, lhs: ValueRef, rhs: ValueRef ) -> ValueRef { let rhs = base::cast_shift_expr_rhs(bx, hir::BinOpKind::Shr, lhs, rhs); // #1877, #10183: Ensure that input is always valid @@ -370,15 +371,15 @@ pub fn build_unchecked_rshift<'a, 'tcx>( } } -fn shift_mask_rhs<'a, 'tcx>(bx: &Builder<'a, 'tcx>, rhs: ValueRef) -> ValueRef { +fn shift_mask_rhs(bx: &Builder<'a, 'll, 'tcx>, rhs: ValueRef) -> ValueRef { let rhs_llty = val_ty(rhs); bx.and(rhs, shift_mask_val(bx, rhs_llty, rhs_llty, false)) } -pub fn shift_mask_val<'a, 'tcx>( - bx: &Builder<'a, 'tcx>, - llty: Type, - mask_llty: Type, +pub fn shift_mask_val( + bx: &Builder<'a, 'll, 'tcx>, + llty: &'ll Type, + mask_llty: &'ll Type, invert: bool ) -> ValueRef { let kind = llty.kind(); diff --git a/src/librustc_codegen_llvm/consts.rs b/src/librustc_codegen_llvm/consts.rs index f0b5f4b887971..956e81f746da9 100644 --- a/src/librustc_codegen_llvm/consts.rs +++ b/src/librustc_codegen_llvm/consts.rs @@ -31,15 +31,15 @@ use rustc::hir::{self, CodegenFnAttrs, CodegenFnAttrFlags}; use std::ffi::{CStr, CString}; -pub fn ptrcast(val: ValueRef, ty: Type) -> ValueRef { +pub fn ptrcast(val: ValueRef, ty: &Type) -> ValueRef { unsafe { - llvm::LLVMConstPointerCast(val, ty.to_ref()) + llvm::LLVMConstPointerCast(val, ty) } } -pub fn bitcast(val: ValueRef, ty: Type) -> ValueRef { +pub fn bitcast(val: ValueRef, ty: &Type) -> ValueRef { unsafe { - llvm::LLVMConstBitCast(val, ty.to_ref()) + llvm::LLVMConstBitCast(val, ty) } } @@ -294,7 +294,7 @@ pub fn codegen_static<'a, 'tcx>( let mut val_llty = val_ty(v); let v = if val_llty == Type::i1(cx) { val_llty = Type::i8(cx); - llvm::LLVMConstZExt(v, val_llty.to_ref()) + llvm::LLVMConstZExt(v, val_llty) } else { v }; @@ -316,7 +316,7 @@ pub fn codegen_static<'a, 'tcx>( let visibility = llvm::LLVMRustGetVisibility(g); let new_g = llvm::LLVMRustGetOrInsertGlobal( - cx.llmod, name_string.as_ptr(), val_llty.to_ref()); + cx.llmod, name_string.as_ptr(), val_llty); llvm::LLVMRustSetLinkage(new_g, linkage); llvm::LLVMRustSetVisibility(new_g, visibility); @@ -411,7 +411,7 @@ pub fn codegen_static<'a, 'tcx>( if attrs.flags.contains(CodegenFnAttrFlags::USED) { // This static will be stored in the llvm.used variable which is an array of i8* - let cast = llvm::LLVMConstPointerCast(g, Type::i8p(cx).to_ref()); + let cast = llvm::LLVMConstPointerCast(g, Type::i8p(cx)); cx.used_statics.borrow_mut().push(cast); } } diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs index f91173226c48d..1616d54a77aaa 100644 --- a/src/librustc_codegen_llvm/context.rs +++ b/src/librustc_codegen_llvm/context.rs @@ -89,10 +89,10 @@ pub struct CodegenCx<'a, 'tcx: 'a> { /// See http://llvm.org/docs/LangRef.html#the-llvm-used-global-variable for details pub used_statics: RefCell>, - pub lltypes: RefCell, Option), Type>>, - pub scalar_lltypes: RefCell, Type>>, + pub lltypes: RefCell, Option), &'a Type>>, + pub scalar_lltypes: RefCell, &'a Type>>, pub pointee_infos: RefCell, Size), Option>>, - pub isize_ty: Type, + pub isize_ty: &'a Type, pub dbg_cx: Option>, @@ -373,7 +373,7 @@ impl<'b, 'tcx> CodegenCx<'b, 'tcx> { } else { "rust_eh_personality" }; - let fty = Type::variadic_func(&[], &Type::i32(self)); + let fty = Type::variadic_func(&[], Type::i32(self)); declare::declare_cfn(self, name, fty) } }; @@ -439,25 +439,25 @@ impl<'b, 'tcx> CodegenCx<'b, 'tcx> { } } -impl<'a, 'tcx> ty::layout::HasDataLayout for &'a CodegenCx<'a, 'tcx> { +impl ty::layout::HasDataLayout for &'a CodegenCx<'ll, 'tcx> { fn data_layout(&self) -> &ty::layout::TargetDataLayout { &self.tcx.data_layout } } -impl<'a, 'tcx> HasTargetSpec for &'a CodegenCx<'a, 'tcx> { +impl HasTargetSpec for &'a CodegenCx<'ll, 'tcx> { fn target_spec(&self) -> &Target { &self.tcx.sess.target.target } } -impl<'a, 'tcx> ty::layout::HasTyCtxt<'tcx> for &'a CodegenCx<'a, 'tcx> { +impl ty::layout::HasTyCtxt<'tcx> for &'a CodegenCx<'ll, 'tcx> { fn tcx<'b>(&'b self) -> TyCtxt<'b, 'tcx, 'tcx> { self.tcx } } -impl<'a, 'tcx> LayoutOf for &'a CodegenCx<'a, 'tcx> { +impl LayoutOf for &'a CodegenCx<'ll, 'tcx> { type Ty = Ty<'tcx>; type TyLayout = TyLayout<'tcx>; @@ -475,7 +475,7 @@ fn declare_intrinsic(cx: &CodegenCx, key: &str) -> Option { macro_rules! ifn { ($name:expr, fn() -> $ret:expr) => ( if key == $name { - let f = declare::declare_cfn(cx, $name, Type::func(&[], &$ret)); + let f = declare::declare_cfn(cx, $name, Type::func(&[], $ret)); llvm::SetUnnamedAddr(f, false); cx.intrinsics.borrow_mut().insert($name, f.clone()); return Some(f); @@ -483,7 +483,7 @@ fn declare_intrinsic(cx: &CodegenCx, key: &str) -> Option { ); ($name:expr, fn(...) -> $ret:expr) => ( if key == $name { - let f = declare::declare_cfn(cx, $name, Type::variadic_func(&[], &$ret)); + let f = declare::declare_cfn(cx, $name, Type::variadic_func(&[], $ret)); llvm::SetUnnamedAddr(f, false); cx.intrinsics.borrow_mut().insert($name, f.clone()); return Some(f); @@ -491,7 +491,7 @@ fn declare_intrinsic(cx: &CodegenCx, key: &str) -> Option { ); ($name:expr, fn($($arg:expr),*) -> $ret:expr) => ( if key == $name { - let f = declare::declare_cfn(cx, $name, Type::func(&[$($arg),*], &$ret)); + let f = declare::declare_cfn(cx, $name, Type::func(&[$($arg),*], $ret)); llvm::SetUnnamedAddr(f, false); cx.intrinsics.borrow_mut().insert($name, f.clone()); return Some(f); @@ -513,14 +513,14 @@ fn declare_intrinsic(cx: &CodegenCx, key: &str) -> Option { let t_f32 = Type::f32(cx); let t_f64 = Type::f64(cx); - let t_v2f32 = Type::vector(&t_f32, 2); - let t_v4f32 = Type::vector(&t_f32, 4); - let t_v8f32 = Type::vector(&t_f32, 8); - let t_v16f32 = Type::vector(&t_f32, 16); + let t_v2f32 = Type::vector(t_f32, 2); + let t_v4f32 = Type::vector(t_f32, 4); + let t_v8f32 = Type::vector(t_f32, 8); + let t_v16f32 = Type::vector(t_f32, 16); - let t_v2f64 = Type::vector(&t_f64, 2); - let t_v4f64 = Type::vector(&t_f64, 4); - let t_v8f64 = Type::vector(&t_f64, 8); + let t_v2f64 = Type::vector(t_f64, 2); + let t_v4f64 = Type::vector(t_f64, 4); + let t_v8f64 = Type::vector(t_f64, 8); ifn!("llvm.memcpy.p0i8.p0i8.i16", fn(i8p, i8p, t_i16, t_i32, i1) -> void); ifn!("llvm.memcpy.p0i8.p0i8.i32", fn(i8p, i8p, t_i32, t_i32, i1) -> void); diff --git a/src/librustc_codegen_llvm/debuginfo/gdb.rs b/src/librustc_codegen_llvm/debuginfo/gdb.rs index 4014ad95b9dd0..de43a4522cc28 100644 --- a/src/librustc_codegen_llvm/debuginfo/gdb.rs +++ b/src/librustc_codegen_llvm/debuginfo/gdb.rs @@ -54,7 +54,7 @@ pub fn get_or_insert_gdb_debug_scripts_section_global(cx: &CodegenCx) let section_contents = b"\x01gdb_load_rust_pretty_printers.py\0"; unsafe { - let llvm_type = Type::array(&Type::i8(cx), + let llvm_type = Type::array(Type::i8(cx), section_contents.len() as u64); let section_var = declare::define_global(cx, section_var_name, diff --git a/src/librustc_codegen_llvm/debuginfo/mod.rs b/src/librustc_codegen_llvm/debuginfo/mod.rs index d4b5110603369..3336e46ea797d 100644 --- a/src/librustc_codegen_llvm/debuginfo/mod.rs +++ b/src/librustc_codegen_llvm/debuginfo/mod.rs @@ -471,14 +471,16 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, } } -pub fn declare_local<'a, 'tcx>(bx: &Builder<'a, 'tcx>, - dbg_context: &FunctionDebugContext, - variable_name: ast::Name, - variable_type: Ty<'tcx>, - scope_metadata: DIScope, - variable_access: VariableAccess, - variable_kind: VariableKind, - span: Span) { +pub fn declare_local( + bx: &Builder<'a, 'll, 'tcx>, + dbg_context: &FunctionDebugContext, + variable_name: ast::Name, + variable_type: Ty<'tcx>, + scope_metadata: DIScope, + variable_access: VariableAccess, + variable_kind: VariableKind, + span: Span, +) { assert!(!dbg_context.get_ref(span).source_locations_enabled.get()); let cx = bx.cx; diff --git a/src/librustc_codegen_llvm/debuginfo/utils.rs b/src/librustc_codegen_llvm/debuginfo/utils.rs index 85cddb0a580a5..69d457f218832 100644 --- a/src/librustc_codegen_llvm/debuginfo/utils.rs +++ b/src/librustc_codegen_llvm/debuginfo/utils.rs @@ -49,8 +49,7 @@ pub fn span_start(cx: &CodegenCx, span: Span) -> syntax_pos::Loc { } #[inline] -pub fn debug_context<'a, 'tcx>(cx: &'a CodegenCx<'a, 'tcx>) - -> &'a CrateDebugContext<'a, 'tcx> { +pub fn debug_context(cx: &'a CodegenCx<'ll, 'tcx>) -> &'a CrateDebugContext<'a, 'tcx> { cx.dbg_cx.as_ref().unwrap() } diff --git a/src/librustc_codegen_llvm/declare.rs b/src/librustc_codegen_llvm/declare.rs index fdc84f914f502..1a9346ed8933d 100644 --- a/src/librustc_codegen_llvm/declare.rs +++ b/src/librustc_codegen_llvm/declare.rs @@ -40,13 +40,13 @@ use std::ffi::CString; /// /// If there’s a value with the same name already declared, the function will /// return its ValueRef instead. -pub fn declare_global(cx: &CodegenCx, name: &str, ty: Type) -> llvm::ValueRef { +pub fn declare_global(cx: &CodegenCx, name: &str, ty: &Type) -> llvm::ValueRef { debug!("declare_global(name={:?})", name); let namebuf = CString::new(name).unwrap_or_else(|_|{ bug!("name {:?} contains an interior null byte", name) }); unsafe { - llvm::LLVMRustGetOrInsertGlobal(cx.llmod, namebuf.as_ptr(), ty.to_ref()) + llvm::LLVMRustGetOrInsertGlobal(cx.llmod, namebuf.as_ptr(), ty) } } @@ -55,13 +55,13 @@ pub fn declare_global(cx: &CodegenCx, name: &str, ty: Type) -> llvm::ValueRef { /// /// If there’s a value with the same name already declared, the function will /// update the declaration and return existing ValueRef instead. -fn declare_raw_fn(cx: &CodegenCx, name: &str, callconv: llvm::CallConv, ty: Type) -> ValueRef { +fn declare_raw_fn(cx: &CodegenCx, name: &str, callconv: llvm::CallConv, ty: &Type) -> ValueRef { debug!("declare_raw_fn(name={:?}, ty={:?})", name, ty); let namebuf = CString::new(name).unwrap_or_else(|_|{ bug!("name {:?} contains an interior null byte", name) }); let llfn = unsafe { - llvm::LLVMRustGetOrInsertFunction(cx.llmod, namebuf.as_ptr(), ty.to_ref()) + llvm::LLVMRustGetOrInsertFunction(cx.llmod, namebuf.as_ptr(), ty) }; llvm::SetFunctionCallConv(llfn, callconv); @@ -115,7 +115,7 @@ fn declare_raw_fn(cx: &CodegenCx, name: &str, callconv: llvm::CallConv, ty: Type /// /// If there’s a value with the same name already declared, the function will /// update the declaration and return existing ValueRef instead. -pub fn declare_cfn(cx: &CodegenCx, name: &str, fn_type: Type) -> ValueRef { +pub fn declare_cfn(cx: &CodegenCx, name: &str, fn_type: &Type) -> ValueRef { declare_raw_fn(cx, name, llvm::CCallConv, fn_type) } @@ -154,7 +154,7 @@ pub fn declare_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, name: &str, /// return None if the name already has a definition associated with it. In that /// case an error should be reported to the user, because it usually happens due /// to user’s fault (e.g. misuse of #[no_mangle] or #[export_name] attributes). -pub fn define_global(cx: &CodegenCx, name: &str, ty: Type) -> Option { +pub fn define_global(cx: &CodegenCx, name: &str, ty: &Type) -> Option { if get_defined_value(cx, name).is_some() { None } else { diff --git a/src/librustc_codegen_llvm/glue.rs b/src/librustc_codegen_llvm/glue.rs index c7275d0940185..992ff9f24de13 100644 --- a/src/librustc_codegen_llvm/glue.rs +++ b/src/librustc_codegen_llvm/glue.rs @@ -23,7 +23,7 @@ use rustc::ty::layout::LayoutOf; use rustc::ty::{self, Ty}; use value::Value; -pub fn size_and_align_of_dst<'a, 'tcx>(bx: &Builder<'a, 'tcx>, t: Ty<'tcx>, info: ValueRef) +pub fn size_and_align_of_dst(bx: &Builder<'a, 'll, 'tcx>, t: Ty<'tcx>, info: ValueRef) -> (ValueRef, ValueRef) { debug!("calculate size of DST: {}; with lost info: {:?}", t, Value(info)); diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index 9c5c0f730c161..7dca1e907a857 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -85,12 +85,14 @@ fn get_simple_intrinsic(cx: &CodegenCx, name: &str) -> Option { /// Remember to add all intrinsics here, in librustc_typeck/check/mod.rs, /// and in libcore/intrinsics.rs; if you need access to any llvm intrinsics, /// add them to librustc_codegen_llvm/context.rs -pub fn codegen_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>, - callee_ty: Ty<'tcx>, - fn_ty: &FnType<'tcx, Ty<'tcx>>, - args: &[OperandRef<'tcx>], - llresult: ValueRef, - span: Span) { +pub fn codegen_intrinsic_call( + bx: &Builder<'a, 'll, 'tcx>, + callee_ty: Ty<'tcx>, + fn_ty: &FnType<'tcx, Ty<'tcx>>, + args: &[OperandRef<'tcx>], + llresult: ValueRef, + span: Span, +) { let cx = bx.cx; let tcx = cx.tcx; @@ -545,7 +547,7 @@ pub fn codegen_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>, assert_eq!(x.len(), 1); x.into_iter().next().unwrap() } - fn ty_to_type(cx: &CodegenCx, t: &intrinsics::Type) -> Vec { + fn ty_to_type(cx: &CodegenCx<'ll, '_>, t: &intrinsics::Type) -> Vec<&'ll Type> { use intrinsics::Type::*; match *t { Void => vec![Type::void(cx)], @@ -567,7 +569,7 @@ pub fn codegen_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>, Vector(ref t, ref llvm_elem, length) => { let t = llvm_elem.as_ref().unwrap_or(t); let elem = one(ty_to_type(cx, t)); - vec![Type::vector(&elem, length as u64)] + vec![Type::vector(elem, length as u64)] } Aggregate(false, ref contents) => { let elems = contents.iter() @@ -587,10 +589,11 @@ pub fn codegen_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>, // qux` to be converted into `foo, bar, baz, qux`, integer // arguments to be truncated as needed and pointers to be // cast. - fn modify_as_needed<'a, 'tcx>(bx: &Builder<'a, 'tcx>, - t: &intrinsics::Type, - arg: &OperandRef<'tcx>) - -> Vec + fn modify_as_needed( + bx: &Builder<'a, 'll, 'tcx>, + t: &intrinsics::Type, + arg: &OperandRef<'tcx>, + ) -> Vec { match *t { intrinsics::Type::Aggregate(true, ref contents) => { @@ -616,7 +619,7 @@ pub fn codegen_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>, } intrinsics::Type::Vector(_, Some(ref llvm_elem), length) => { let llvm_elem = one(ty_to_type(bx.cx, llvm_elem)); - vec![bx.bitcast(arg.immediate(), Type::vector(&llvm_elem, length as u64))] + vec![bx.bitcast(arg.immediate(), Type::vector(llvm_elem, length as u64))] } intrinsics::Type::Integer(_, width, llvm_width) if width != llvm_width => { // the LLVM intrinsic uses a smaller integer @@ -644,7 +647,7 @@ pub fn codegen_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>, intrinsics::IntrinsicDef::Named(name) => { let f = declare::declare_cfn(cx, name, - Type::func(&inputs, &outputs)); + Type::func(&inputs, outputs)); bx.call(f, &llargs, None) } }; @@ -677,14 +680,15 @@ pub fn codegen_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>, } } -fn copy_intrinsic<'a, 'tcx>(bx: &Builder<'a, 'tcx>, - allow_overlap: bool, - volatile: bool, - ty: Ty<'tcx>, - dst: ValueRef, - src: ValueRef, - count: ValueRef) - -> ValueRef { +fn copy_intrinsic( + bx: &Builder<'a, 'll, 'tcx>, + allow_overlap: bool, + volatile: bool, + ty: Ty<'tcx>, + dst: ValueRef, + src: ValueRef, + count: ValueRef, +) -> ValueRef { let cx = bx.cx; let (size, align) = cx.size_and_align_of(ty); let size = C_usize(cx, size.bytes()); @@ -712,8 +716,8 @@ fn copy_intrinsic<'a, 'tcx>(bx: &Builder<'a, 'tcx>, None) } -fn memset_intrinsic<'a, 'tcx>( - bx: &Builder<'a, 'tcx>, +fn memset_intrinsic( + bx: &Builder<'a, 'll, 'tcx>, volatile: bool, ty: Ty<'tcx>, dst: ValueRef, @@ -728,8 +732,8 @@ fn memset_intrinsic<'a, 'tcx>( call_memset(bx, dst, val, bx.mul(size, count), align, volatile) } -fn try_intrinsic<'a, 'tcx>( - bx: &Builder<'a, 'tcx>, +fn try_intrinsic( + bx: &Builder<'a, 'll, 'tcx>, cx: &CodegenCx, func: ValueRef, data: ValueRef, @@ -754,12 +758,14 @@ fn try_intrinsic<'a, 'tcx>( // instructions are meant to work for all targets, as of the time of this // writing, however, LLVM does not recommend the usage of these new instructions // as the old ones are still more optimized. -fn codegen_msvc_try<'a, 'tcx>(bx: &Builder<'a, 'tcx>, - cx: &CodegenCx, - func: ValueRef, - data: ValueRef, - local_ptr: ValueRef, - dest: ValueRef) { +fn codegen_msvc_try( + bx: &Builder<'a, 'll, 'tcx>, + cx: &CodegenCx, + func: ValueRef, + data: ValueRef, + local_ptr: ValueRef, + dest: ValueRef, +) { let llfn = get_rust_try_fn(cx, &mut |bx| { let cx = bx.cx; @@ -862,12 +868,14 @@ fn codegen_msvc_try<'a, 'tcx>(bx: &Builder<'a, 'tcx>, // function calling it, and that function may already have other personality // functions in play. By calling a shim we're guaranteed that our shim will have // the right personality function. -fn codegen_gnu_try<'a, 'tcx>(bx: &Builder<'a, 'tcx>, - cx: &CodegenCx, - func: ValueRef, - data: ValueRef, - local_ptr: ValueRef, - dest: ValueRef) { +fn codegen_gnu_try( + bx: &Builder<'a, 'll, 'tcx>, + cx: &CodegenCx, + func: ValueRef, + data: ValueRef, + local_ptr: ValueRef, + dest: ValueRef, +) { let llfn = get_rust_try_fn(cx, &mut |bx| { let cx = bx.cx; @@ -922,12 +930,13 @@ fn codegen_gnu_try<'a, 'tcx>(bx: &Builder<'a, 'tcx>, // Helper function to give a Block to a closure to codegen a shim function. // This is currently primarily used for the `try` intrinsic functions above. -fn gen_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, - name: &str, - inputs: Vec>, - output: Ty<'tcx>, - codegen: &mut dyn for<'b> FnMut(Builder<'b, 'tcx>)) - -> ValueRef { +fn gen_fn<'ll, 'tcx>( + cx: &CodegenCx<'ll, 'tcx>, + name: &str, + inputs: Vec>, + output: Ty<'tcx>, + codegen: &mut dyn FnMut(Builder<'_, 'll, 'tcx>), +) -> ValueRef { let rust_fn_ty = cx.tcx.mk_fn_ptr(ty::Binder::bind(cx.tcx.mk_fn_sig( inputs.into_iter(), output, @@ -945,9 +954,10 @@ fn gen_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, // catch exceptions. // // This function is only generated once and is then cached. -fn get_rust_try_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, - codegen: &mut dyn for<'b> FnMut(Builder<'b, 'tcx>)) - -> ValueRef { +fn get_rust_try_fn<'ll, 'tcx>( + cx: &CodegenCx<'ll, 'tcx>, + codegen: &mut dyn FnMut(Builder<'_, 'll, 'tcx>), +) -> ValueRef { if let Some(llfn) = cx.rust_try_fn.get() { return llfn; } @@ -972,13 +982,13 @@ fn span_invalid_monomorphization_error(a: &Session, b: Span, c: &str) { span_err!(a, b, E0511, "{}", c); } -fn generic_simd_intrinsic<'a, 'tcx>( - bx: &Builder<'a, 'tcx>, +fn generic_simd_intrinsic( + bx: &Builder<'a, 'll, 'tcx>, name: &str, callee_ty: Ty<'tcx>, args: &[OperandRef<'tcx>], ret_ty: Ty<'tcx>, - llret_ty: Type, + llret_ty: &'ll Type, span: Span ) -> Result { // macros for error handling: @@ -1145,19 +1155,20 @@ fn generic_simd_intrinsic<'a, 'tcx>( } // truncate the mask to a vector of i1s let i1 = Type::i1(bx.cx); - let i1xn = Type::vector(&i1, m_len as u64); + let i1xn = Type::vector(i1, m_len as u64); let m_i1s = bx.trunc(args[0].immediate(), i1xn); return Ok(bx.select(m_i1s, args[1].immediate(), args[2].immediate())); } - fn simd_simple_float_intrinsic<'a, 'tcx>(name: &str, - in_elem: &::rustc::ty::TyS, - in_ty: &::rustc::ty::TyS, - in_len: usize, - bx: &Builder<'a, 'tcx>, - span: Span, - args: &[OperandRef<'tcx>]) - -> Result { + fn simd_simple_float_intrinsic( + name: &str, + in_elem: &::rustc::ty::TyS, + in_ty: &::rustc::ty::TyS, + in_len: usize, + bx: &Builder<'a, 'll, 'tcx>, + span: Span, + args: &[OperandRef<'tcx>], + ) -> Result { macro_rules! emit_error { ($msg: tt) => { emit_error!($msg, ) @@ -1283,8 +1294,8 @@ fn generic_simd_intrinsic<'a, 'tcx>( } } - fn llvm_vector_ty(cx: &CodegenCx, elem_ty: ty::Ty, vec_len: usize, - mut no_pointers: usize) -> Type { + fn llvm_vector_ty(cx: &CodegenCx<'ll, '_>, elem_ty: ty::Ty, vec_len: usize, + mut no_pointers: usize) -> &'ll Type { // FIXME: use cx.layout_of(ty).llvm_type() ? let mut elem_ty = match elem_ty.sty { ty::TyInt(v) => Type::int_from_ty(cx, v), @@ -1296,7 +1307,7 @@ fn generic_simd_intrinsic<'a, 'tcx>( elem_ty = elem_ty.ptr_to(); no_pointers -= 1; } - Type::vector(&elem_ty, vec_len as u64) + Type::vector(elem_ty, vec_len as u64) } @@ -1379,7 +1390,7 @@ fn generic_simd_intrinsic<'a, 'tcx>( // Truncate the mask vector to a vector of i1s: let (mask, mask_ty) = { let i1 = Type::i1(bx.cx); - let i1xn = Type::vector(&i1, in_len as u64); + let i1xn = Type::vector(i1, in_len as u64); (bx.trunc(args[2].immediate(), i1xn), i1xn) }; @@ -1395,7 +1406,7 @@ fn generic_simd_intrinsic<'a, 'tcx>( llvm_elem_vec_str, llvm_pointer_vec_str); let f = declare::declare_cfn(bx.cx, &llvm_intrinsic, Type::func(&[llvm_pointer_vec_ty, alignment_ty, mask_ty, - llvm_elem_vec_ty], &llvm_elem_vec_ty)); + llvm_elem_vec_ty], llvm_elem_vec_ty)); llvm::SetUnnamedAddr(f, false); let v = bx.call(f, &[args[1].immediate(), alignment, mask, args[0].immediate()], None); @@ -1476,7 +1487,7 @@ fn generic_simd_intrinsic<'a, 'tcx>( // Truncate the mask vector to a vector of i1s: let (mask, mask_ty) = { let i1 = Type::i1(bx.cx); - let i1xn = Type::vector(&i1, in_len as u64); + let i1xn = Type::vector(i1, in_len as u64); (bx.trunc(args[2].immediate(), i1xn), i1xn) }; @@ -1496,7 +1507,7 @@ fn generic_simd_intrinsic<'a, 'tcx>( Type::func(&[llvm_elem_vec_ty, llvm_pointer_vec_ty, alignment_ty, - mask_ty], &ret_t)); + mask_ty], ret_t)); llvm::SetUnnamedAddr(f, false); let v = bx.call(f, &[args[0].immediate(), args[1].immediate(), alignment, mask], None); @@ -1629,7 +1640,7 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#, // boolean reductions operate on vectors of i1s: let i1 = Type::i1(bx.cx); - let i1xn = Type::vector(&i1, in_len as u64); + let i1xn = Type::vector(i1, in_len as u64); bx.trunc(args[0].immediate(), i1xn) }; return match in_elem.sty { diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index 9d94869dab06e..1c7988fa8d555 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -377,8 +377,7 @@ pub enum ThreadLocalMode { // Opaque pointer types extern { pub type Module; } extern { pub type Context; } -extern { pub type Type_opaque; } -pub type TypeRef = *mut Type_opaque; +extern { pub type Type; } extern { pub type Value_opaque; } pub type ValueRef = *mut Value_opaque; extern { pub type Metadata_opaque; } @@ -517,55 +516,55 @@ extern "C" { pub fn LLVMRustAppendModuleInlineAsm(M: &Module, Asm: *const c_char); /// See llvm::LLVMTypeKind::getTypeID. - pub fn LLVMRustGetTypeKind(Ty: TypeRef) -> TypeKind; + pub fn LLVMRustGetTypeKind(Ty: &Type) -> TypeKind; // Operations on integer types - pub fn LLVMInt1TypeInContext(C: &Context) -> TypeRef; - pub fn LLVMInt8TypeInContext(C: &Context) -> TypeRef; - pub fn LLVMInt16TypeInContext(C: &Context) -> TypeRef; - pub fn LLVMInt32TypeInContext(C: &Context) -> TypeRef; - pub fn LLVMInt64TypeInContext(C: &Context) -> TypeRef; - pub fn LLVMIntTypeInContext(C: &Context, NumBits: c_uint) -> TypeRef; + pub fn LLVMInt1TypeInContext(C: &Context) -> &Type; + pub fn LLVMInt8TypeInContext(C: &Context) -> &Type; + pub fn LLVMInt16TypeInContext(C: &Context) -> &Type; + pub fn LLVMInt32TypeInContext(C: &Context) -> &Type; + pub fn LLVMInt64TypeInContext(C: &Context) -> &Type; + pub fn LLVMIntTypeInContext(C: &Context, NumBits: c_uint) -> &Type; - pub fn LLVMGetIntTypeWidth(IntegerTy: TypeRef) -> c_uint; + pub fn LLVMGetIntTypeWidth(IntegerTy: &Type) -> c_uint; // Operations on real types - pub fn LLVMFloatTypeInContext(C: &Context) -> TypeRef; - pub fn LLVMDoubleTypeInContext(C: &Context) -> TypeRef; + pub fn LLVMFloatTypeInContext(C: &Context) -> &Type; + pub fn LLVMDoubleTypeInContext(C: &Context) -> &Type; // Operations on function types - pub fn LLVMFunctionType(ReturnType: TypeRef, - ParamTypes: *const TypeRef, + pub fn LLVMFunctionType(ReturnType: &'a Type, + ParamTypes: *const &'a Type, 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); + -> &'a Type; + pub fn LLVMGetReturnType(FunctionTy: &Type) -> &Type; + pub fn LLVMCountParamTypes(FunctionTy: &Type) -> c_uint; + pub fn LLVMGetParamTypes(FunctionTy: &'a Type, Dest: *mut &'a Type); // Operations on struct types - pub fn LLVMStructTypeInContext(C: &Context, - ElementTypes: *const TypeRef, + pub fn LLVMStructTypeInContext(C: &'a Context, + ElementTypes: *const &'a Type, ElementCount: c_uint, Packed: Bool) - -> TypeRef; - pub fn LLVMIsPackedStruct(StructTy: TypeRef) -> Bool; + -> &'a Type; + pub fn LLVMIsPackedStruct(StructTy: &Type) -> 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 LLVMRustArrayType(ElementType: &Type, ElementCount: u64) -> &Type; + pub fn LLVMPointerType(ElementType: &Type, AddressSpace: c_uint) -> &Type; + pub fn LLVMVectorType(ElementType: &Type, ElementCount: c_uint) -> &Type; - pub fn LLVMGetElementType(Ty: TypeRef) -> TypeRef; - pub fn LLVMGetVectorSize(VectorTy: TypeRef) -> c_uint; + pub fn LLVMGetElementType(Ty: &Type) -> &Type; + pub fn LLVMGetVectorSize(VectorTy: &Type) -> c_uint; // Operations on other types - pub fn LLVMVoidTypeInContext(C: &Context) -> TypeRef; - pub fn LLVMX86MMXTypeInContext(C: &Context) -> TypeRef; - pub fn LLVMRustMetadataTypeInContext(C: &Context) -> TypeRef; + pub fn LLVMVoidTypeInContext(C: &Context) -> &Type; + pub fn LLVMX86MMXTypeInContext(C: &Context) -> &Type; + pub fn LLVMRustMetadataTypeInContext(C: &Context) -> &Type; // Operations on all values - pub fn LLVMTypeOf(Val: ValueRef) -> TypeRef; + pub fn LLVMTypeOf(Val: &Value_opaque) -> &Type; pub fn LLVMGetValueName(Val: ValueRef) -> *const c_char; pub fn LLVMSetValueName(Val: ValueRef, Name: *const c_char); pub fn LLVMReplaceAllUsesWith(OldVal: ValueRef, NewVal: ValueRef); @@ -580,10 +579,10 @@ extern "C" { pub fn LLVMGetOperand(Val: ValueRef, Index: c_uint) -> ValueRef; // Operations on constants of any type - pub fn LLVMConstNull(Ty: TypeRef) -> ValueRef; + pub fn LLVMConstNull(Ty: &Type) -> 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; + pub fn LLVMGetUndef(Ty: &Type) -> ValueRef; // Operations on metadata pub fn LLVMMDStringInContext(C: &Context, Str: *const c_char, SLen: c_uint) -> ValueRef; @@ -591,8 +590,8 @@ extern "C" { pub fn LLVMAddNamedMetadataOperand(M: &Module, 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 LLVMConstInt(IntTy: &Type, N: c_ulonglong, SignExtend: Bool) -> ValueRef; + pub fn LLVMConstIntOfArbitraryPrecision(IntTy: &Type, 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, @@ -612,14 +611,14 @@ extern "C" { Packed: Bool) -> ValueRef; - pub fn LLVMConstArray(ElementTy: TypeRef, + pub fn LLVMConstArray(ElementTy: &Type, 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 LLVMSizeOf(Ty: &Type) -> ValueRef; pub fn LLVMConstNeg(ConstantVal: ValueRef) -> ValueRef; pub fn LLVMConstFNeg(ConstantVal: ValueRef) -> ValueRef; pub fn LLVMConstNot(ConstantVal: ValueRef) -> ValueRef; @@ -651,23 +650,23 @@ extern "C" { 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 LLVMConstTrunc(ConstantVal: ValueRef, ToType: &Type) -> ValueRef; + pub fn LLVMConstZExt(ConstantVal: ValueRef, ToType: &Type) -> ValueRef; + pub fn LLVMConstUIToFP(ConstantVal: ValueRef, ToType: &Type) -> ValueRef; + pub fn LLVMConstSIToFP(ConstantVal: ValueRef, ToType: &Type) -> ValueRef; + pub fn LLVMConstFPToUI(ConstantVal: ValueRef, ToType: &Type) -> ValueRef; + pub fn LLVMConstFPToSI(ConstantVal: ValueRef, ToType: &Type) -> ValueRef; + pub fn LLVMConstPtrToInt(ConstantVal: ValueRef, ToType: &Type) -> ValueRef; + pub fn LLVMConstIntToPtr(ConstantVal: ValueRef, ToType: &Type) -> ValueRef; + pub fn LLVMConstBitCast(ConstantVal: ValueRef, ToType: &Type) -> ValueRef; + pub fn LLVMConstPointerCast(ConstantVal: ValueRef, ToType: &Type) -> ValueRef; + pub fn LLVMConstIntCast(ConstantVal: ValueRef, ToType: &Type, isSigned: Bool) -> ValueRef; + pub fn LLVMConstFPCast(ConstantVal: ValueRef, ToType: &Type) -> ValueRef; pub fn LLVMConstExtractValue(AggConstant: ValueRef, IdxList: *const c_uint, NumIdx: c_uint) -> ValueRef; - pub fn LLVMConstInlineAsm(Ty: TypeRef, + pub fn LLVMConstInlineAsm(Ty: &Type, AsmString: *const c_char, Constraints: *const c_char, HasSideEffects: Bool, @@ -690,9 +689,9 @@ extern "C" { // Operations on global variables pub fn LLVMIsAGlobalVariable(GlobalVar: ValueRef) -> ValueRef; - pub fn LLVMAddGlobal(M: &Module, Ty: TypeRef, Name: *const c_char) -> ValueRef; + pub fn LLVMAddGlobal(M: &Module, Ty: &Type, Name: *const c_char) -> ValueRef; pub fn LLVMGetNamedGlobal(M: &Module, Name: *const c_char) -> ValueRef; - pub fn LLVMRustGetOrInsertGlobal(M: &Module, Name: *const c_char, T: TypeRef) -> ValueRef; + pub fn LLVMRustGetOrInsertGlobal(M: &Module, Name: *const c_char, T: &Type) -> ValueRef; pub fn LLVMGetFirstGlobal(M: &Module) -> ValueRef; pub fn LLVMGetNextGlobal(GlobalVar: ValueRef) -> ValueRef; pub fn LLVMDeleteGlobal(GlobalVar: ValueRef); @@ -706,13 +705,13 @@ extern "C" { pub fn LLVMSetTailCall(CallInst: ValueRef, IsTailCall: Bool); // Operations on functions - pub fn LLVMAddFunction(M: &Module, Name: *const c_char, FunctionTy: TypeRef) -> ValueRef; + pub fn LLVMAddFunction(M: &Module, Name: *const c_char, FunctionTy: &Type) -> ValueRef; pub fn LLVMGetNamedFunction(M: &Module, Name: *const c_char) -> ValueRef; pub fn LLVMGetFirstFunction(M: &Module) -> ValueRef; pub fn LLVMGetNextFunction(Fn: ValueRef) -> ValueRef; pub fn LLVMRustGetOrInsertFunction(M: &Module, Name: *const c_char, - FunctionTy: TypeRef) + FunctionTy: &Type) -> ValueRef; pub fn LLVMSetFunctionCallConv(Fn: ValueRef, CC: c_uint); pub fn LLVMRustAddAlignmentAttr(Fn: ValueRef, index: c_uint, bytes: u32); @@ -801,7 +800,7 @@ extern "C" { Name: *const c_char) -> ValueRef; pub fn LLVMBuildLandingPad(B: BuilderRef, - Ty: TypeRef, + Ty: &Type, PersFn: ValueRef, NumClauses: c_uint, Name: *const c_char) @@ -989,7 +988,7 @@ extern "C" { pub fn LLVMRustSetHasUnsafeAlgebra(Instr: ValueRef); // Memory - pub fn LLVMBuildAlloca(B: BuilderRef, Ty: TypeRef, Name: *const c_char) -> ValueRef; + pub fn LLVMBuildAlloca(B: BuilderRef, Ty: &Type, 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; @@ -1024,98 +1023,98 @@ extern "C" { // Casts pub fn LLVMBuildTrunc(B: BuilderRef, Val: ValueRef, - DestTy: TypeRef, + DestTy: &Type, Name: *const c_char) -> ValueRef; pub fn LLVMBuildZExt(B: BuilderRef, Val: ValueRef, - DestTy: TypeRef, + DestTy: &Type, Name: *const c_char) -> ValueRef; pub fn LLVMBuildSExt(B: BuilderRef, Val: ValueRef, - DestTy: TypeRef, + DestTy: &Type, Name: *const c_char) -> ValueRef; pub fn LLVMBuildFPToUI(B: BuilderRef, Val: ValueRef, - DestTy: TypeRef, + DestTy: &Type, Name: *const c_char) -> ValueRef; pub fn LLVMBuildFPToSI(B: BuilderRef, Val: ValueRef, - DestTy: TypeRef, + DestTy: &Type, Name: *const c_char) -> ValueRef; pub fn LLVMBuildUIToFP(B: BuilderRef, Val: ValueRef, - DestTy: TypeRef, + DestTy: &Type, Name: *const c_char) -> ValueRef; pub fn LLVMBuildSIToFP(B: BuilderRef, Val: ValueRef, - DestTy: TypeRef, + DestTy: &Type, Name: *const c_char) -> ValueRef; pub fn LLVMBuildFPTrunc(B: BuilderRef, Val: ValueRef, - DestTy: TypeRef, + DestTy: &Type, Name: *const c_char) -> ValueRef; pub fn LLVMBuildFPExt(B: BuilderRef, Val: ValueRef, - DestTy: TypeRef, + DestTy: &Type, Name: *const c_char) -> ValueRef; pub fn LLVMBuildPtrToInt(B: BuilderRef, Val: ValueRef, - DestTy: TypeRef, + DestTy: &Type, Name: *const c_char) -> ValueRef; pub fn LLVMBuildIntToPtr(B: BuilderRef, Val: ValueRef, - DestTy: TypeRef, + DestTy: &Type, Name: *const c_char) -> ValueRef; pub fn LLVMBuildBitCast(B: BuilderRef, Val: ValueRef, - DestTy: TypeRef, + DestTy: &Type, Name: *const c_char) -> ValueRef; pub fn LLVMBuildZExtOrBitCast(B: BuilderRef, Val: ValueRef, - DestTy: TypeRef, + DestTy: &Type, Name: *const c_char) -> ValueRef; pub fn LLVMBuildSExtOrBitCast(B: BuilderRef, Val: ValueRef, - DestTy: TypeRef, + DestTy: &Type, Name: *const c_char) -> ValueRef; pub fn LLVMBuildTruncOrBitCast(B: BuilderRef, Val: ValueRef, - DestTy: TypeRef, + DestTy: &Type, Name: *const c_char) -> ValueRef; pub fn LLVMBuildCast(B: BuilderRef, Op: Opcode, Val: ValueRef, - DestTy: TypeRef, + DestTy: &Type, Name: *const c_char) -> ValueRef; pub fn LLVMBuildPointerCast(B: BuilderRef, Val: ValueRef, - DestTy: TypeRef, + DestTy: &Type, Name: *const c_char) -> ValueRef; pub fn LLVMRustBuildIntCast(B: BuilderRef, Val: ValueRef, - DestTy: TypeRef, + DestTy: &Type, IsSized: bool) -> ValueRef; pub fn LLVMBuildFPCast(B: BuilderRef, Val: ValueRef, - DestTy: TypeRef, + DestTy: &Type, Name: *const c_char) -> ValueRef; @@ -1134,7 +1133,7 @@ extern "C" { -> ValueRef; // Miscellaneous instructions - pub fn LLVMBuildPhi(B: BuilderRef, Ty: TypeRef, Name: *const c_char) -> ValueRef; + pub fn LLVMBuildPhi(B: BuilderRef, Ty: &Type, Name: *const c_char) -> ValueRef; pub fn LLVMRustBuildCall(B: BuilderRef, Fn: ValueRef, Args: *const ValueRef, @@ -1150,7 +1149,7 @@ extern "C" { -> ValueRef; pub fn LLVMBuildVAArg(B: BuilderRef, list: ValueRef, - Ty: TypeRef, + Ty: &Type, Name: *const c_char) -> ValueRef; pub fn LLVMBuildExtractElement(B: BuilderRef, @@ -1347,15 +1346,15 @@ extern "C" { /// Print the pass timings since static dtors aren't picking them up. pub fn LLVMRustPrintPassTimings(); - pub fn LLVMStructCreateNamed(C: &Context, Name: *const c_char) -> TypeRef; + pub fn LLVMStructCreateNamed(C: &Context, Name: *const c_char) -> &Type; - pub fn LLVMStructSetBody(StructTy: TypeRef, - ElementTypes: *const TypeRef, + pub fn LLVMStructSetBody(StructTy: &'a Type, + ElementTypes: *const &'a Type, ElementCount: c_uint, Packed: Bool); /// Prepares inline assembly. - pub fn LLVMRustInlineAsm(Ty: TypeRef, + pub fn LLVMRustInlineAsm(Ty: &Type, AsmString: *const c_char, Constraints: *const c_char, SideEffects: Bool, @@ -1587,7 +1586,7 @@ extern "C" { pub fn LLVMRustDIBuilderCreateOpDeref() -> i64; pub fn LLVMRustDIBuilderCreateOpPlusUconst() -> i64; - pub fn LLVMRustWriteTypeToString(Type: TypeRef, s: RustStringRef); + pub fn LLVMRustWriteTypeToString(Type: &Type, s: RustStringRef); pub fn LLVMRustWriteValueToString(value_ref: ValueRef, s: RustStringRef); pub fn LLVMIsAConstantInt(value_ref: ValueRef) -> ValueRef; diff --git a/src/librustc_codegen_llvm/meth.rs b/src/librustc_codegen_llvm/meth.rs index 21bbdf31dcb52..c313c04d8047a 100644 --- a/src/librustc_codegen_llvm/meth.rs +++ b/src/librustc_codegen_llvm/meth.rs @@ -33,7 +33,7 @@ impl<'a, 'tcx> VirtualIndex { VirtualIndex(index as u64 + 3) } - pub fn get_fn(self, bx: &Builder<'a, 'tcx>, + pub fn get_fn(self, bx: &Builder<'a, 'll, 'tcx>, llvtable: ValueRef, fn_ty: &FnType<'tcx, Ty<'tcx>>) -> ValueRef { // Load the data pointer from the object. @@ -48,7 +48,7 @@ impl<'a, 'tcx> VirtualIndex { ptr } - pub fn get_usize(self, bx: &Builder<'a, 'tcx>, llvtable: ValueRef) -> ValueRef { + pub fn get_usize(self, bx: &Builder<'a, 'll, 'tcx>, llvtable: ValueRef) -> ValueRef { // Load the data pointer from the object. debug!("get_int({:?}, {:?})", Value(llvtable), self); diff --git a/src/librustc_codegen_llvm/mir/analyze.rs b/src/librustc_codegen_llvm/mir/analyze.rs index e105baba8aa2e..7bf548a6b12d5 100644 --- a/src/librustc_codegen_llvm/mir/analyze.rs +++ b/src/librustc_codegen_llvm/mir/analyze.rs @@ -22,7 +22,7 @@ use rustc::ty::layout::LayoutOf; use type_of::LayoutLlvmExt; use super::FunctionCx; -pub fn non_ssa_locals<'a, 'tcx>(fx: &FunctionCx<'a, 'tcx>) -> BitVector { +pub fn non_ssa_locals(fx: &FunctionCx<'a, 'll, 'tcx>) -> BitVector { let mir = fx.mir; let mut analyzer = LocalAnalyzer::new(fx); @@ -51,8 +51,8 @@ pub fn non_ssa_locals<'a, 'tcx>(fx: &FunctionCx<'a, 'tcx>) -> BitVector { - fx: &'mir FunctionCx<'a, 'tcx>, +struct LocalAnalyzer<'mir, 'a: 'mir, 'll: 'a, 'tcx: 'll> { + fx: &'mir FunctionCx<'a, 'll, 'tcx>, dominators: Dominators, non_ssa_locals: BitVector, // The location of the first visited direct assignment to each @@ -60,8 +60,8 @@ struct LocalAnalyzer<'mir, 'a: 'mir, 'tcx: 'a> { first_assignment: IndexVec } -impl<'mir, 'a, 'tcx> LocalAnalyzer<'mir, 'a, 'tcx> { - fn new(fx: &'mir FunctionCx<'a, 'tcx>) -> LocalAnalyzer<'mir, 'a, 'tcx> { +impl LocalAnalyzer<'mir, 'a, 'll, 'tcx> { + fn new(fx: &'mir FunctionCx<'a, 'll, 'tcx>) -> Self { let invalid_location = mir::BasicBlock::new(fx.mir.basic_blocks().len()).start_location(); let mut analyzer = LocalAnalyzer { @@ -102,7 +102,7 @@ impl<'mir, 'a, 'tcx> LocalAnalyzer<'mir, 'a, 'tcx> { } } -impl<'mir, 'a, 'tcx> Visitor<'tcx> for LocalAnalyzer<'mir, 'a, 'tcx> { +impl Visitor<'tcx> for LocalAnalyzer<'mir, 'a, 'll, 'tcx> { fn visit_assign(&mut self, block: mir::BasicBlock, place: &mir::Place<'tcx>, diff --git a/src/librustc_codegen_llvm/mir/block.rs b/src/librustc_codegen_llvm/mir/block.rs index dc4b9e0ae99d8..349978c18b7e6 100644 --- a/src/librustc_codegen_llvm/mir/block.rs +++ b/src/librustc_codegen_llvm/mir/block.rs @@ -33,7 +33,7 @@ use super::place::PlaceRef; use super::operand::OperandRef; use super::operand::OperandValue::{Pair, Ref, Immediate}; -impl<'a, 'tcx> FunctionCx<'a, 'tcx> { +impl FunctionCx<'a, 'll, 'tcx> { pub fn codegen_block(&mut self, bb: mir::BasicBlock) { let mut bx = self.build_block(bb); let data = &self.mir[bb]; @@ -48,7 +48,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { } fn codegen_terminator(&mut self, - mut bx: Builder<'a, 'tcx>, + mut bx: Builder<'a, 'll, 'tcx>, bb: mir::BasicBlock, terminator: &mir::Terminator<'tcx>) { @@ -110,7 +110,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { let do_call = | this: &mut Self, - bx: Builder<'a, 'tcx>, + bx: Builder<'a, 'll, 'tcx>, fn_ty: FnType<'tcx, Ty<'tcx>>, fn_ptr: ValueRef, llargs: &[ValueRef], @@ -627,7 +627,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { } fn codegen_argument(&mut self, - bx: &Builder<'a, 'tcx>, + bx: &Builder<'a, 'll, 'tcx>, op: OperandRef<'tcx>, llargs: &mut Vec, arg: &ArgType<'tcx, Ty<'tcx>>) { @@ -706,7 +706,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { } fn codegen_arguments_untupled(&mut self, - bx: &Builder<'a, 'tcx>, + bx: &Builder<'a, 'll, 'tcx>, operand: &mir::Operand<'tcx>, llargs: &mut Vec, args: &[ArgType<'tcx, Ty<'tcx>>]) { @@ -728,7 +728,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { } } - fn get_personality_slot(&mut self, bx: &Builder<'a, 'tcx>) -> PlaceRef<'tcx> { + fn get_personality_slot(&mut self, bx: &Builder<'a, 'll, 'tcx>) -> PlaceRef<'tcx> { let cx = bx.cx; if let Some(slot) = self.personality_slot { slot @@ -777,7 +777,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { bx.llbb() } - fn landing_pad_type(&self) -> Type { + fn landing_pad_type(&self) -> &'ll Type { let cx = self.cx; Type::struct_(cx, &[Type::i8p(cx), Type::i32(cx)], false) } @@ -791,17 +791,17 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { }) } - pub fn new_block(&self, name: &str) -> Builder<'a, 'tcx> { + pub fn new_block(&self, name: &str) -> Builder<'a, 'll, 'tcx> { Builder::new_block(self.cx, self.llfn, name) } - pub fn build_block(&self, bb: mir::BasicBlock) -> Builder<'a, 'tcx> { + pub fn build_block(&self, bb: mir::BasicBlock) -> Builder<'a, 'll, 'tcx> { let bx = Builder::with_cx(self.cx); bx.position_at_end(self.blocks[bb]); bx } - fn make_return_dest(&mut self, bx: &Builder<'a, 'tcx>, + fn make_return_dest(&mut self, bx: &Builder<'a, 'll, 'tcx>, dest: &mir::Place<'tcx>, fn_ret: &ArgType<'tcx, Ty<'tcx>>, llargs: &mut Vec, is_intrinsic: bool) -> ReturnDest<'tcx> { @@ -857,7 +857,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { } } - fn codegen_transmute(&mut self, bx: &Builder<'a, 'tcx>, + fn codegen_transmute(&mut self, bx: &Builder<'a, 'll, 'tcx>, src: &mir::Operand<'tcx>, dst: &mir::Place<'tcx>) { if let mir::Place::Local(index) = *dst { @@ -884,7 +884,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { } } - fn codegen_transmute_into(&mut self, bx: &Builder<'a, 'tcx>, + fn codegen_transmute_into(&mut self, bx: &Builder<'a, 'll, 'tcx>, src: &mir::Operand<'tcx>, dst: PlaceRef<'tcx>) { let src = self.codegen_operand(bx, src); @@ -897,7 +897,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { // Stores the return value of a function call into it's final location. fn store_return(&mut self, - bx: &Builder<'a, 'tcx>, + bx: &Builder<'a, 'll, 'tcx>, dest: ReturnDest<'tcx>, ret_ty: &ArgType<'tcx, Ty<'tcx>>, llval: ValueRef) { diff --git a/src/librustc_codegen_llvm/mir/constant.rs b/src/librustc_codegen_llvm/mir/constant.rs index 0d682d5d6f6a1..3fc86af3e6d40 100644 --- a/src/librustc_codegen_llvm/mir/constant.rs +++ b/src/librustc_codegen_llvm/mir/constant.rs @@ -33,7 +33,7 @@ use super::FunctionCx; pub fn scalar_to_llvm(cx: &CodegenCx, cv: Scalar, layout: &layout::Scalar, - llty: Type) -> ValueRef { + llty: &Type) -> ValueRef { let bitsize = if layout.is_bool() { 1 } else { layout.value.size(cx).bits() }; match cv { Scalar::Bits { defined, .. } if (defined as u64) < bitsize || defined == 0 => { @@ -42,7 +42,7 @@ pub fn scalar_to_llvm(cx: &CodegenCx, Scalar::Bits { bits, .. } => { let llval = C_uint_big(Type::ix(cx, bitsize), bits); if layout.value == layout::Pointer { - unsafe { llvm::LLVMConstIntToPtr(llval, llty.to_ref()) } + unsafe { llvm::LLVMConstIntToPtr(llval, llty) } } else { consts::bitcast(llval, llty) } @@ -73,7 +73,7 @@ pub fn scalar_to_llvm(cx: &CodegenCx, 1, ) }; if layout.value != layout::Pointer { - unsafe { llvm::LLVMConstPtrToInt(llval, llty.to_ref()) } + unsafe { llvm::LLVMConstPtrToInt(llval, llty) } } else { consts::bitcast(llval, llty) } @@ -135,10 +135,10 @@ pub fn codegen_static_initializer<'a, 'tcx>( Ok((const_alloc_to_llvm(cx, alloc), alloc)) } -impl<'a, 'tcx> FunctionCx<'a, 'tcx> { +impl FunctionCx<'a, 'll, 'tcx> { fn fully_evaluate( &mut self, - bx: &Builder<'a, 'tcx>, + bx: &Builder<'a, 'll, 'tcx>, constant: &'tcx ty::Const<'tcx>, ) -> Result<&'tcx ty::Const<'tcx>, Lrc>> { match constant.val { @@ -158,7 +158,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { pub fn eval_mir_constant( &mut self, - bx: &Builder<'a, 'tcx>, + bx: &Builder<'a, 'll, 'tcx>, constant: &mir::Constant<'tcx>, ) -> Result<&'tcx ty::Const<'tcx>, Lrc>> { let c = self.monomorphize(&constant.literal); @@ -168,7 +168,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { /// process constant containing SIMD shuffle indices pub fn simd_shuffle_indices( &mut self, - bx: &Builder<'a, 'tcx>, + bx: &Builder<'a, 'll, 'tcx>, span: Span, ty: Ty<'tcx>, constant: Result<&'tcx ty::Const<'tcx>, Lrc>>, diff --git a/src/librustc_codegen_llvm/mir/mod.rs b/src/librustc_codegen_llvm/mir/mod.rs index 5fb4cbfb982d5..4b33459740c55 100644 --- a/src/librustc_codegen_llvm/mir/mod.rs +++ b/src/librustc_codegen_llvm/mir/mod.rs @@ -43,7 +43,7 @@ use rustc::mir::traversal; use self::operand::{OperandRef, OperandValue}; /// Master context for codegenning from MIR. -pub struct FunctionCx<'a, 'tcx:'a> { +pub struct FunctionCx<'a, 'll: 'a, 'tcx: 'll> { instance: Instance<'tcx>, mir: &'a mir::Mir<'tcx>, @@ -52,7 +52,7 @@ pub struct FunctionCx<'a, 'tcx:'a> { llfn: ValueRef, - cx: &'a CodegenCx<'a, 'tcx>, + cx: &'a CodegenCx<'ll, 'tcx>, fn_ty: FnType<'tcx, Ty<'tcx>>, @@ -106,7 +106,7 @@ pub struct FunctionCx<'a, 'tcx:'a> { param_substs: &'tcx Substs<'tcx>, } -impl<'a, 'tcx> FunctionCx<'a, 'tcx> { +impl FunctionCx<'a, 'll, 'tcx> { pub fn monomorphize(&self, value: &T) -> T where T: TypeFoldable<'tcx> { @@ -198,8 +198,8 @@ impl<'a, 'tcx> LocalRef<'tcx> { /////////////////////////////////////////////////////////////////////////// -pub fn codegen_mir<'a, 'tcx: 'a>( - cx: &'a CodegenCx<'a, 'tcx>, +pub fn codegen_mir( + cx: &'a CodegenCx<'ll, 'tcx>, llfn: ValueRef, mir: &'a Mir<'tcx>, instance: Instance<'tcx>, @@ -344,9 +344,9 @@ pub fn codegen_mir<'a, 'tcx: 'a>( } } -fn create_funclets<'a, 'tcx>( +fn create_funclets( mir: &'a Mir<'tcx>, - bx: &Builder<'a, 'tcx>, + bx: &Builder<'a, 'll, 'tcx>, cleanup_kinds: &IndexVec, block_bxs: &IndexVec) -> (IndexVec>, @@ -413,11 +413,12 @@ fn create_funclets<'a, 'tcx>( /// Produce, for each argument, a `ValueRef` pointing at the /// argument's value. As arguments are places, these are always /// indirect. -fn arg_local_refs<'a, 'tcx>(bx: &Builder<'a, 'tcx>, - fx: &FunctionCx<'a, 'tcx>, - scopes: &IndexVec, - memory_locals: &BitVector) - -> Vec> { +fn arg_local_refs( + bx: &Builder<'a, 'll, 'tcx>, + fx: &FunctionCx<'a, 'll, 'tcx>, + scopes: &IndexVec, + memory_locals: &BitVector, +) -> Vec> { let mir = fx.mir; let tcx = bx.tcx(); let mut idx = 0; diff --git a/src/librustc_codegen_llvm/mir/operand.rs b/src/librustc_codegen_llvm/mir/operand.rs index 78c83f200a517..790dbae447bd4 100644 --- a/src/librustc_codegen_llvm/mir/operand.rs +++ b/src/librustc_codegen_llvm/mir/operand.rs @@ -92,7 +92,7 @@ impl<'a, 'tcx> OperandRef<'tcx> { } } - pub fn from_const(bx: &Builder<'a, 'tcx>, + pub fn from_const(bx: &Builder<'a, 'll, 'tcx>, val: &'tcx ty::Const<'tcx>) -> Result, Lrc>> { let layout = bx.cx.layout_of(val.ty); @@ -174,7 +174,7 @@ impl<'a, 'tcx> OperandRef<'tcx> { /// If this operand is a `Pair`, we return an aggregate with the two values. /// For other cases, see `immediate`. - pub fn immediate_or_packed_pair(self, bx: &Builder<'a, 'tcx>) -> ValueRef { + pub fn immediate_or_packed_pair(self, bx: &Builder<'a, 'll, 'tcx>) -> ValueRef { if let OperandValue::Pair(a, b) = self.val { let llty = self.layout.llvm_type(bx.cx); debug!("Operand::immediate_or_packed_pair: packing {:?} into {:?}", @@ -190,7 +190,7 @@ impl<'a, 'tcx> OperandRef<'tcx> { } /// If the type is a pair, we return a `Pair`, otherwise, an `Immediate`. - pub fn from_immediate_or_packed_pair(bx: &Builder<'a, 'tcx>, + pub fn from_immediate_or_packed_pair(bx: &Builder<'a, 'll, 'tcx>, llval: ValueRef, layout: TyLayout<'tcx>) -> OperandRef<'tcx> { @@ -208,7 +208,7 @@ impl<'a, 'tcx> OperandRef<'tcx> { OperandRef { val, layout } } - pub fn extract_field(&self, bx: &Builder<'a, 'tcx>, i: usize) -> OperandRef<'tcx> { + pub fn extract_field(&self, bx: &Builder<'a, 'll, 'tcx>, i: usize) -> OperandRef<'tcx> { let field = self.layout.field(bx.cx, i); let offset = self.layout.fields.offset(i); @@ -267,23 +267,23 @@ impl<'a, 'tcx> OperandRef<'tcx> { } impl<'a, 'tcx> OperandValue { - pub fn store(self, bx: &Builder<'a, 'tcx>, dest: PlaceRef<'tcx>) { + pub fn store(self, bx: &Builder<'a, 'll, 'tcx>, dest: PlaceRef<'tcx>) { self.store_with_flags(bx, dest, MemFlags::empty()); } - pub fn volatile_store(self, bx: &Builder<'a, 'tcx>, dest: PlaceRef<'tcx>) { + pub fn volatile_store(self, bx: &Builder<'a, 'll, 'tcx>, dest: PlaceRef<'tcx>) { self.store_with_flags(bx, dest, MemFlags::VOLATILE); } - pub fn unaligned_volatile_store(self, bx: &Builder<'a, 'tcx>, dest: PlaceRef<'tcx>) { + pub fn unaligned_volatile_store(self, bx: &Builder<'a, 'll, 'tcx>, dest: PlaceRef<'tcx>) { self.store_with_flags(bx, dest, MemFlags::VOLATILE | MemFlags::UNALIGNED); } - pub fn nontemporal_store(self, bx: &Builder<'a, 'tcx>, dest: PlaceRef<'tcx>) { + pub fn nontemporal_store(self, bx: &Builder<'a, 'll, 'tcx>, dest: PlaceRef<'tcx>) { self.store_with_flags(bx, dest, MemFlags::NONTEMPORAL); } - fn store_with_flags(self, bx: &Builder<'a, 'tcx>, dest: PlaceRef<'tcx>, flags: MemFlags) { + fn store_with_flags(self, bx: &Builder<'a, 'll, 'tcx>, dest: PlaceRef<'tcx>, flags: MemFlags) { debug!("OperandRef::store: operand={:?}, dest={:?}", self, dest); // Avoid generating stores of zero-sized values, because the only way to have a zero-sized // value is through `undef`, and store itself is useless. @@ -310,9 +310,9 @@ impl<'a, 'tcx> OperandValue { } } -impl<'a, 'tcx> FunctionCx<'a, 'tcx> { +impl FunctionCx<'a, 'll, 'tcx> { fn maybe_codegen_consume_direct(&mut self, - bx: &Builder<'a, 'tcx>, + bx: &Builder<'a, 'll, 'tcx>, place: &mir::Place<'tcx>) -> Option> { @@ -360,7 +360,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { } pub fn codegen_consume(&mut self, - bx: &Builder<'a, 'tcx>, + bx: &Builder<'a, 'll, 'tcx>, place: &mir::Place<'tcx>) -> OperandRef<'tcx> { @@ -384,7 +384,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { } pub fn codegen_operand(&mut self, - bx: &Builder<'a, 'tcx>, + bx: &Builder<'a, 'll, 'tcx>, operand: &mir::Operand<'tcx>) -> OperandRef<'tcx> { diff --git a/src/librustc_codegen_llvm/mir/place.rs b/src/librustc_codegen_llvm/mir/place.rs index aff29b06b8f31..9cb513e21586a 100644 --- a/src/librustc_codegen_llvm/mir/place.rs +++ b/src/librustc_codegen_llvm/mir/place.rs @@ -56,7 +56,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> { } pub fn from_const_alloc( - bx: &Builder<'a, 'tcx>, + bx: &Builder<'a, 'll, 'tcx>, layout: TyLayout<'tcx>, alloc: &mir::interpret::Allocation, offset: Size, @@ -73,7 +73,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> { PlaceRef::new_sized(llval, layout, alloc.align) } - pub fn alloca(bx: &Builder<'a, 'tcx>, layout: TyLayout<'tcx>, name: &str) + pub fn alloca(bx: &Builder<'a, 'll, 'tcx>, layout: TyLayout<'tcx>, name: &str) -> PlaceRef<'tcx> { debug!("alloca({:?}: {:?})", name, layout); let tmp = bx.alloca(layout.llvm_type(bx.cx), name, layout.align); @@ -98,7 +98,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> { !self.llextra.is_null() } - pub fn load(&self, bx: &Builder<'a, 'tcx>) -> OperandRef<'tcx> { + pub fn load(&self, bx: &Builder<'a, 'll, 'tcx>) -> OperandRef<'tcx> { debug!("PlaceRef::load: {:?}", self); assert!(!self.has_extra()); @@ -162,7 +162,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> { } /// Access a field, at a point when the value's case is known. - pub fn project_field(self, bx: &Builder<'a, 'tcx>, ix: usize) -> PlaceRef<'tcx> { + pub fn project_field(self, bx: &Builder<'a, 'll, 'tcx>, ix: usize) -> PlaceRef<'tcx> { let cx = bx.cx; let field = self.layout.field(cx, ix); let offset = self.layout.fields.offset(ix); @@ -266,7 +266,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> { } /// Obtain the actual discriminant of a value. - pub fn codegen_get_discr(self, bx: &Builder<'a, 'tcx>, cast_to: Ty<'tcx>) -> ValueRef { + pub fn codegen_get_discr(self, bx: &Builder<'a, 'll, 'tcx>, cast_to: Ty<'tcx>) -> ValueRef { let cast_to = bx.cx.layout_of(cast_to).immediate_llvm_type(bx.cx); if self.layout.abi == layout::Abi::Uninhabited { return C_undef(cast_to); @@ -330,7 +330,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> { /// Set the discriminant for a new value of the given case of the given /// representation. - pub fn codegen_set_discr(&self, bx: &Builder<'a, 'tcx>, variant_index: usize) { + pub fn codegen_set_discr(&self, bx: &Builder<'a, 'll, 'tcx>, variant_index: usize) { if self.layout.for_variant(bx.cx, variant_index).abi == layout::Abi::Uninhabited { return; } @@ -384,7 +384,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> { } } - pub fn project_index(&self, bx: &Builder<'a, 'tcx>, llindex: ValueRef) + pub fn project_index(&self, bx: &Builder<'a, 'll, 'tcx>, llindex: ValueRef) -> PlaceRef<'tcx> { PlaceRef { llval: bx.inbounds_gep(self.llval, &[C_usize(bx.cx, 0), llindex]), @@ -394,7 +394,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> { } } - pub fn project_downcast(&self, bx: &Builder<'a, 'tcx>, variant_index: usize) + pub fn project_downcast(&self, bx: &Builder<'a, 'll, 'tcx>, variant_index: usize) -> PlaceRef<'tcx> { let mut downcast = *self; downcast.layout = self.layout.for_variant(bx.cx, variant_index); @@ -406,18 +406,18 @@ impl<'a, 'tcx> PlaceRef<'tcx> { downcast } - pub fn storage_live(&self, bx: &Builder<'a, 'tcx>) { + pub fn storage_live(&self, bx: &Builder<'a, 'll, 'tcx>) { bx.lifetime_start(self.llval, self.layout.size); } - pub fn storage_dead(&self, bx: &Builder<'a, 'tcx>) { + pub fn storage_dead(&self, bx: &Builder<'a, 'll, 'tcx>) { bx.lifetime_end(self.llval, self.layout.size); } } -impl<'a, 'tcx> FunctionCx<'a, 'tcx> { +impl FunctionCx<'a, 'll, 'tcx> { pub fn codegen_place(&mut self, - bx: &Builder<'a, 'tcx>, + bx: &Builder<'a, 'll, 'tcx>, place: &mir::Place<'tcx>) -> PlaceRef<'tcx> { debug!("codegen_place(place={:?})", place); diff --git a/src/librustc_codegen_llvm/mir/rvalue.rs b/src/librustc_codegen_llvm/mir/rvalue.rs index 2e81fc16a5838..ca61f94e42817 100644 --- a/src/librustc_codegen_llvm/mir/rvalue.rs +++ b/src/librustc_codegen_llvm/mir/rvalue.rs @@ -32,12 +32,12 @@ use super::{FunctionCx, LocalRef}; use super::operand::{OperandRef, OperandValue}; use super::place::PlaceRef; -impl<'a, 'tcx> FunctionCx<'a, 'tcx> { +impl FunctionCx<'a, 'll, 'tcx> { pub fn codegen_rvalue(&mut self, - bx: Builder<'a, 'tcx>, + bx: Builder<'a, 'll, 'tcx>, dest: PlaceRef<'tcx>, rvalue: &mir::Rvalue<'tcx>) - -> Builder<'a, 'tcx> + -> Builder<'a, 'll, 'tcx> { debug!("codegen_rvalue(dest.llval={:?}, rvalue={:?})", Value(dest.llval), rvalue); @@ -176,9 +176,9 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { } pub fn codegen_rvalue_operand(&mut self, - bx: Builder<'a, 'tcx>, + bx: Builder<'a, 'll, 'tcx>, rvalue: &mir::Rvalue<'tcx>) - -> (Builder<'a, 'tcx>, OperandRef<'tcx>) + -> (Builder<'a, 'll, 'tcx>, OperandRef<'tcx>) { assert!(self.rvalue_creates_operand(rvalue), "cannot codegen {:?} to operand", rvalue); @@ -512,7 +512,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { } fn evaluate_array_len(&mut self, - bx: &Builder<'a, 'tcx>, + bx: &Builder<'a, 'll, 'tcx>, place: &mir::Place<'tcx>) -> ValueRef { // ZST are passed as operands and require special handling @@ -531,7 +531,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { } pub fn codegen_scalar_binop(&mut self, - bx: &Builder<'a, 'tcx>, + bx: &Builder<'a, 'll, 'tcx>, op: mir::BinOp, lhs: ValueRef, rhs: ValueRef, @@ -597,7 +597,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { } pub fn codegen_fat_ptr_binop(&mut self, - bx: &Builder<'a, 'tcx>, + bx: &Builder<'a, 'll, 'tcx>, op: mir::BinOp, lhs_addr: ValueRef, lhs_extra: ValueRef, @@ -644,7 +644,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { } pub fn codegen_scalar_checked_binop(&mut self, - bx: &Builder<'a, 'tcx>, + bx: &Builder<'a, 'll, 'tcx>, op: mir::BinOp, lhs: ValueRef, rhs: ValueRef, @@ -796,11 +796,11 @@ fn get_overflow_intrinsic(oop: OverflowOp, bx: &Builder, ty: Ty) -> ValueRef { bx.cx.get_intrinsic(&name) } -fn cast_int_to_float(bx: &Builder, +fn cast_int_to_float(bx: &Builder<'_, 'll, '_>, signed: bool, x: ValueRef, - int_ty: Type, - float_ty: Type) -> ValueRef { + int_ty: &'ll Type, + float_ty: &'ll Type) -> ValueRef { // Most integer types, even i128, fit into [-f32::MAX, f32::MAX] after rounding. // It's only u128 -> f32 that can cause overflows (i.e., should yield infinity). // LLVM's uitofp produces undef in those cases, so we manually check for that case. @@ -826,11 +826,11 @@ fn cast_int_to_float(bx: &Builder, } } -fn cast_float_to_int(bx: &Builder, +fn cast_float_to_int(bx: &Builder<'_, 'll, '_>, signed: bool, x: ValueRef, - float_ty: Type, - int_ty: Type) -> ValueRef { + float_ty: &'ll Type, + int_ty: &'ll Type) -> ValueRef { let fptosui_result = if signed { bx.fptosi(x, int_ty) } else { @@ -859,14 +859,14 @@ fn cast_float_to_int(bx: &Builder, // On the other hand, f_max works even if int_ty::MAX is greater than float_ty::MAX. Because // we're rounding towards zero, we just get float_ty::MAX (which is always an integer). // This already happens today with u128::MAX = 2^128 - 1 > f32::MAX. - fn compute_clamp_bounds(signed: bool, int_ty: Type) -> (u128, u128) { + fn compute_clamp_bounds(signed: bool, int_ty: &Type) -> (u128, u128) { let rounded_min = F::from_i128_r(int_min(signed, int_ty), Round::TowardZero); assert_eq!(rounded_min.status, Status::OK); let rounded_max = F::from_u128_r(int_max(signed, int_ty), Round::TowardZero); assert!(rounded_max.value.is_finite()); (rounded_min.value.to_bits(), rounded_max.value.to_bits()) } - fn int_max(signed: bool, int_ty: Type) -> u128 { + fn int_max(signed: bool, int_ty: &Type) -> u128 { let shift_amount = 128 - int_ty.int_width(); if signed { i128::MAX as u128 >> shift_amount @@ -874,7 +874,7 @@ fn cast_float_to_int(bx: &Builder, u128::MAX >> shift_amount } } - fn int_min(signed: bool, int_ty: Type) -> i128 { + fn int_min(signed: bool, int_ty: &Type) -> i128 { if signed { i128::MIN >> (128 - int_ty.int_width()) } else { diff --git a/src/librustc_codegen_llvm/mir/statement.rs b/src/librustc_codegen_llvm/mir/statement.rs index c0cce297ef6a9..06340a3e5d8b4 100644 --- a/src/librustc_codegen_llvm/mir/statement.rs +++ b/src/librustc_codegen_llvm/mir/statement.rs @@ -16,11 +16,11 @@ use builder::Builder; use super::FunctionCx; use super::LocalRef; -impl<'a, 'tcx> FunctionCx<'a, 'tcx> { +impl FunctionCx<'a, 'll, 'tcx> { pub fn codegen_statement(&mut self, - bx: Builder<'a, 'tcx>, + bx: Builder<'a, 'll, 'tcx>, statement: &mir::Statement<'tcx>) - -> Builder<'a, 'tcx> { + -> Builder<'a, 'll, 'tcx> { debug!("codegen_statement(statement={:?})", statement); self.set_debug_loc(&bx, statement.source_info); diff --git a/src/librustc_codegen_llvm/type_.rs b/src/librustc_codegen_llvm/type_.rs index cb77ce0039756..4e3a82f0d74e5 100644 --- a/src/librustc_codegen_llvm/type_.rs +++ b/src/librustc_codegen_llvm/type_.rs @@ -10,8 +10,10 @@ #![allow(non_upper_case_globals)] +pub use llvm::Type; + use llvm; -use llvm::{TypeRef, Bool, False, True, TypeKind}; +use llvm::{Bool, False, True, TypeKind}; use llvm::{Float, Double, X86_FP80, PPC_FP128, FP128}; use context::CodegenCx; @@ -21,121 +23,125 @@ use rustc::ty::layout::{self, Align, Size}; use std::ffi::CString; use std::fmt; -use std::mem; use libc::c_uint; -#[derive(Clone, Copy, PartialEq)] -#[repr(C)] -pub struct Type { - rf: TypeRef +impl PartialEq for Type { + fn eq(&self, other: &Self) -> bool { + self as *const _ == other as *const _ + } } impl fmt::Debug for Type { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.write_str(&llvm::build_string(|s| unsafe { - llvm::LLVMRustWriteTypeToString(self.to_ref(), s); + llvm::LLVMRustWriteTypeToString(self, s); }).expect("non-UTF8 type description from LLVM")) } } -macro_rules! ty { - ($e:expr) => ( Type::from_ref(unsafe { $e })) -} - -/// Wrapper for LLVM TypeRef impl Type { - #[inline(always)] - pub fn from_ref(r: TypeRef) -> Type { - Type { - rf: r + pub fn void(cx: &CodegenCx<'ll, '_>) -> &'ll Type { + unsafe { + llvm::LLVMVoidTypeInContext(cx.llcx) } } - #[inline(always)] // So it doesn't kill --opt-level=0 builds of the compiler - pub fn to_ref(&self) -> TypeRef { - self.rf - } - - pub fn to_ref_slice(slice: &[Type]) -> &[TypeRef] { - unsafe { mem::transmute(slice) } - } - - pub fn void(cx: &CodegenCx) -> Type { - ty!(llvm::LLVMVoidTypeInContext(cx.llcx)) - } - - pub fn metadata(cx: &CodegenCx) -> Type { - ty!(llvm::LLVMRustMetadataTypeInContext(cx.llcx)) + pub fn metadata(cx: &CodegenCx<'ll, '_>) -> &'ll Type { + unsafe { + llvm::LLVMRustMetadataTypeInContext(cx.llcx) + } } - pub fn i1(cx: &CodegenCx) -> Type { - ty!(llvm::LLVMInt1TypeInContext(cx.llcx)) + pub fn i1(cx: &CodegenCx<'ll, '_>) -> &'ll Type { + unsafe { + llvm::LLVMInt1TypeInContext(cx.llcx) + } } - pub fn i8(cx: &CodegenCx) -> Type { - ty!(llvm::LLVMInt8TypeInContext(cx.llcx)) + pub fn i8(cx: &CodegenCx<'ll, '_>) -> &'ll Type { + unsafe { + llvm::LLVMInt8TypeInContext(cx.llcx) + } } - pub fn i8_llcx(llcx: &llvm::Context) -> Type { - ty!(llvm::LLVMInt8TypeInContext(llcx)) + pub fn i8_llcx(llcx: &llvm::Context) -> &Type { + unsafe { + llvm::LLVMInt8TypeInContext(llcx) + } } - pub fn i16(cx: &CodegenCx) -> Type { - ty!(llvm::LLVMInt16TypeInContext(cx.llcx)) + pub fn i16(cx: &CodegenCx<'ll, '_>) -> &'ll Type { + unsafe { + llvm::LLVMInt16TypeInContext(cx.llcx) + } } - pub fn i32(cx: &CodegenCx) -> Type { - ty!(llvm::LLVMInt32TypeInContext(cx.llcx)) + pub fn i32(cx: &CodegenCx<'ll, '_>) -> &'ll Type { + unsafe { + llvm::LLVMInt32TypeInContext(cx.llcx) + } } - pub fn i64(cx: &CodegenCx) -> Type { - ty!(llvm::LLVMInt64TypeInContext(cx.llcx)) + pub fn i64(cx: &CodegenCx<'ll, '_>) -> &'ll Type { + unsafe { + llvm::LLVMInt64TypeInContext(cx.llcx) + } } - pub fn i128(cx: &CodegenCx) -> Type { - ty!(llvm::LLVMIntTypeInContext(cx.llcx, 128)) + pub fn i128(cx: &CodegenCx<'ll, '_>) -> &'ll Type { + unsafe { + llvm::LLVMIntTypeInContext(cx.llcx, 128) + } } // Creates an integer type with the given number of bits, e.g. i24 - pub fn ix(cx: &CodegenCx, num_bits: u64) -> Type { - ty!(llvm::LLVMIntTypeInContext(cx.llcx, num_bits as c_uint)) + pub fn ix(cx: &CodegenCx<'ll, '_>, num_bits: u64) -> &'ll Type { + unsafe { + llvm::LLVMIntTypeInContext(cx.llcx, num_bits as c_uint) + } } // Creates an integer type with the given number of bits, e.g. i24 - pub fn ix_llcx(llcx: &llvm::Context, num_bits: u64) -> Type { - ty!(llvm::LLVMIntTypeInContext(llcx, num_bits as c_uint)) + pub fn ix_llcx(llcx: &llvm::Context, num_bits: u64) -> &Type { + unsafe { + llvm::LLVMIntTypeInContext(llcx, num_bits as c_uint) + } } - pub fn f32(cx: &CodegenCx) -> Type { - ty!(llvm::LLVMFloatTypeInContext(cx.llcx)) + pub fn f32(cx: &CodegenCx<'ll, '_>) -> &'ll Type { + unsafe { + llvm::LLVMFloatTypeInContext(cx.llcx) + } } - pub fn f64(cx: &CodegenCx) -> Type { - ty!(llvm::LLVMDoubleTypeInContext(cx.llcx)) + pub fn f64(cx: &CodegenCx<'ll, '_>) -> &'ll Type { + unsafe { + llvm::LLVMDoubleTypeInContext(cx.llcx) + } } - pub fn bool(cx: &CodegenCx) -> Type { + pub fn bool(cx: &CodegenCx<'ll, '_>) -> &'ll Type { Type::i8(cx) } - pub fn char(cx: &CodegenCx) -> Type { + pub fn char(cx: &CodegenCx<'ll, '_>) -> &'ll Type { Type::i32(cx) } - pub fn i8p(cx: &CodegenCx) -> Type { + pub fn i8p(cx: &CodegenCx<'ll, '_>) -> &'ll Type { Type::i8(cx).ptr_to() } - pub fn i8p_llcx(llcx: &llvm::Context) -> Type { + pub fn i8p_llcx(llcx: &llvm::Context) -> &Type { Type::i8_llcx(llcx).ptr_to() } - pub fn isize(cx: &CodegenCx) -> Type { + pub fn isize(cx: &CodegenCx<'ll, '_>) -> &'ll Type { cx.isize_ty } - pub fn c_int(cx: &CodegenCx) -> Type { + pub fn c_int(cx: &CodegenCx<'ll, '_>) -> &'ll Type { match &cx.tcx.sess.target.target.target_c_int_width[..] { "16" => Type::i16(cx), "32" => Type::i32(cx), @@ -144,7 +150,7 @@ impl Type { } } - pub fn int_from_ty(cx: &CodegenCx, t: ast::IntTy) -> Type { + pub fn int_from_ty(cx: &CodegenCx<'ll, '_>, t: ast::IntTy) -> &'ll Type { match t { ast::IntTy::Isize => cx.isize_ty, ast::IntTy::I8 => Type::i8(cx), @@ -155,7 +161,7 @@ impl Type { } } - pub fn uint_from_ty(cx: &CodegenCx, t: ast::UintTy) -> Type { + pub fn uint_from_ty(cx: &CodegenCx<'ll, '_>, t: ast::UintTy) -> &'ll Type { match t { ast::UintTy::Usize => cx.isize_ty, ast::UintTy::U8 => Type::i8(cx), @@ -166,83 +172,93 @@ impl Type { } } - pub fn float_from_ty(cx: &CodegenCx, t: ast::FloatTy) -> Type { + pub fn float_from_ty(cx: &CodegenCx<'ll, '_>, t: ast::FloatTy) -> &'ll Type { match t { ast::FloatTy::F32 => Type::f32(cx), ast::FloatTy::F64 => Type::f64(cx), } } - pub fn func(args: &[Type], ret: &Type) -> Type { - let slice: &[TypeRef] = Type::to_ref_slice(args); - ty!(llvm::LLVMFunctionType(ret.to_ref(), slice.as_ptr(), - args.len() as c_uint, False)) + pub fn func(args: &[&'ll Type], ret: &'ll Type) -> &'ll Type { + unsafe { + llvm::LLVMFunctionType(ret, args.as_ptr(), + args.len() as c_uint, False) + } } - pub fn variadic_func(args: &[Type], ret: &Type) -> Type { - let slice: &[TypeRef] = Type::to_ref_slice(args); - ty!(llvm::LLVMFunctionType(ret.to_ref(), slice.as_ptr(), - args.len() as c_uint, True)) + pub fn variadic_func(args: &[&'ll Type], ret: &'ll Type) -> &'ll Type { + unsafe { + llvm::LLVMFunctionType(ret, args.as_ptr(), + args.len() as c_uint, True) + } } - pub fn struct_(cx: &CodegenCx, els: &[Type], packed: bool) -> Type { - let els: &[TypeRef] = Type::to_ref_slice(els); - ty!(llvm::LLVMStructTypeInContext(cx.llcx, els.as_ptr(), + pub fn struct_(cx: &CodegenCx<'ll, '_>, els: &[&'ll Type], packed: bool) -> &'ll Type { + unsafe { + llvm::LLVMStructTypeInContext(cx.llcx, els.as_ptr(), els.len() as c_uint, - packed as Bool)) + packed as Bool) + } } - pub fn named_struct(cx: &CodegenCx, name: &str) -> Type { + pub fn named_struct(cx: &CodegenCx<'ll, '_>, name: &str) -> &'ll Type { let name = CString::new(name).unwrap(); - ty!(llvm::LLVMStructCreateNamed(cx.llcx, name.as_ptr())) + unsafe { + llvm::LLVMStructCreateNamed(cx.llcx, name.as_ptr()) + } } - pub fn array(ty: &Type, len: u64) -> Type { - ty!(llvm::LLVMRustArrayType(ty.to_ref(), len)) + pub fn array(ty: &Type, len: u64) -> &Type { + unsafe { + llvm::LLVMRustArrayType(ty, len) + } } - pub fn vector(ty: &Type, len: u64) -> Type { - ty!(llvm::LLVMVectorType(ty.to_ref(), len as c_uint)) + pub fn vector(ty: &Type, len: u64) -> &Type { + unsafe { + llvm::LLVMVectorType(ty, len as c_uint) + } } pub fn kind(&self) -> TypeKind { unsafe { - llvm::LLVMRustGetTypeKind(self.to_ref()) + llvm::LLVMRustGetTypeKind(self) } } - pub fn set_struct_body(&mut self, els: &[Type], packed: bool) { - let slice: &[TypeRef] = Type::to_ref_slice(els); + pub fn set_struct_body(&'ll self, els: &[&'ll Type], packed: bool) { unsafe { - llvm::LLVMStructSetBody(self.to_ref(), slice.as_ptr(), + llvm::LLVMStructSetBody(self, els.as_ptr(), els.len() as c_uint, packed as Bool) } } - pub fn ptr_to(&self) -> Type { - ty!(llvm::LLVMPointerType(self.to_ref(), 0)) + pub fn ptr_to(&self) -> &Type { + unsafe { + llvm::LLVMPointerType(self, 0) + } } - pub fn element_type(&self) -> Type { + pub fn element_type(&self) -> &Type { unsafe { - Type::from_ref(llvm::LLVMGetElementType(self.to_ref())) + llvm::LLVMGetElementType(self) } } /// Return the number of elements in `self` if it is a LLVM vector type. pub fn vector_length(&self) -> usize { unsafe { - llvm::LLVMGetVectorSize(self.to_ref()) as usize + llvm::LLVMGetVectorSize(self) as usize } } - pub fn func_params(&self) -> Vec { + pub fn func_params(&self) -> Vec<&Type> { unsafe { - let n_args = llvm::LLVMCountParamTypes(self.to_ref()) as usize; - let mut args = vec![Type { rf: 0 as *mut _ }; n_args]; - llvm::LLVMGetParamTypes(self.to_ref(), - args.as_mut_ptr() as *mut TypeRef); + let n_args = llvm::LLVMCountParamTypes(self) as usize; + let mut args = Vec::with_capacity(n_args); + llvm::LLVMGetParamTypes(self, args.as_mut_ptr()); + args.set_len(n_args); args } } @@ -260,11 +276,11 @@ impl Type { /// Retrieve the bit width of the integer type `self`. pub fn int_width(&self) -> u64 { unsafe { - llvm::LLVMGetIntTypeWidth(self.to_ref()) as u64 + llvm::LLVMGetIntTypeWidth(self) as u64 } } - pub fn from_integer(cx: &CodegenCx, i: layout::Integer) -> Type { + pub fn from_integer(cx: &CodegenCx<'ll, '_>, i: layout::Integer) -> &'ll Type { use rustc::ty::layout::Integer::*; match i { I8 => Type::i8(cx), @@ -277,7 +293,7 @@ impl Type { /// Return a LLVM type that has at most the required alignment, /// as a conservative approximation for unknown pointee types. - pub fn pointee_for_abi_align(cx: &CodegenCx, align: Align) -> Type { + pub fn pointee_for_abi_align(cx: &CodegenCx<'ll, '_>, align: Align) -> &'ll Type { // FIXME(eddyb) We could find a better approximation if ity.align < align. let ity = layout::Integer::approximate_abi_align(cx, align); Type::from_integer(cx, ity) @@ -285,15 +301,17 @@ impl Type { /// Return a LLVM type that has at most the required alignment, /// and exactly the required size, as a best-effort padding array. - pub fn padding_filler(cx: &CodegenCx, size: Size, align: Align) -> Type { + pub fn padding_filler(cx: &CodegenCx<'ll, '_>, size: Size, align: Align) -> &'ll Type { let unit = layout::Integer::approximate_abi_align(cx, align); let size = size.bytes(); let unit_size = unit.size().bytes(); assert_eq!(size % unit_size, 0); - Type::array(&Type::from_integer(cx, unit), size / unit_size) + Type::array(Type::from_integer(cx, unit), size / unit_size) } - pub fn x86_mmx(cx: &CodegenCx) -> Type { - ty!(llvm::LLVMX86MMXTypeInContext(cx.llcx)) + pub fn x86_mmx(cx: &CodegenCx<'ll, '_>) -> &'ll Type { + unsafe { + llvm::LLVMX86MMXTypeInContext(cx.llcx) + } } } diff --git a/src/librustc_codegen_llvm/type_of.rs b/src/librustc_codegen_llvm/type_of.rs index 4728d7717a1e1..5fd4f15acd157 100644 --- a/src/librustc_codegen_llvm/type_of.rs +++ b/src/librustc_codegen_llvm/type_of.rs @@ -23,8 +23,8 @@ use std::fmt::Write; fn uncached_llvm_type<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, layout: TyLayout<'tcx>, - defer: &mut Option<(Type, TyLayout<'tcx>)>) - -> Type { + defer: &mut Option<(&'a Type, TyLayout<'tcx>)>) + -> &'a Type { match layout.abi { layout::Abi::Scalar(_) => bug!("handled elsewhere"), layout::Abi::Vector { ref element, count } => { @@ -42,7 +42,7 @@ fn uncached_llvm_type<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, return Type::x86_mmx(cx) } else { let element = layout.scalar_llvm_type_at(cx, element, Size::ZERO); - return Type::vector(&element, count); + return Type::vector(element, count); } } layout::Abi::ScalarPair(..) => { @@ -96,7 +96,7 @@ fn uncached_llvm_type<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, } } layout::FieldPlacement::Array { count, .. } => { - Type::array(&layout.field(cx, 0).llvm_type(cx), count) + Type::array(layout.field(cx, 0).llvm_type(cx), count) } layout::FieldPlacement::Arbitrary { .. } => { match name { @@ -116,14 +116,14 @@ fn uncached_llvm_type<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, fn struct_llfields<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, layout: TyLayout<'tcx>) - -> (Vec, bool) { + -> (Vec<&'a Type>, bool) { debug!("struct_llfields: {:#?}", layout); let field_count = layout.fields.count(); let mut packed = false; let mut offset = Size::ZERO; let mut prev_align = layout.align; - let mut result: Vec = Vec::with_capacity(1 + field_count * 2); + let mut result: Vec<_> = Vec::with_capacity(1 + field_count * 2); for i in layout.fields.index_by_increasing_offset() { let field = layout.field(cx, i); packed |= layout.align.abi() < field.align.abi(); @@ -201,12 +201,12 @@ pub struct PointeeInfo { pub trait LayoutLlvmExt<'tcx> { fn is_llvm_immediate(&self) -> bool; fn is_llvm_scalar_pair<'a>(&self) -> bool; - fn llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> Type; - fn immediate_llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> Type; + fn llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> &'a Type; + fn immediate_llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> &'a Type; fn scalar_llvm_type_at<'a>(&self, cx: &CodegenCx<'a, 'tcx>, - scalar: &layout::Scalar, offset: Size) -> Type; + scalar: &layout::Scalar, offset: Size) -> &'a Type; fn scalar_pair_element_llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>, - index: usize, immediate: bool) -> Type; + index: usize, immediate: bool) -> &'a Type; fn llvm_field_index(&self, index: usize) -> u64; fn pointee_info_at<'a>(&self, cx: &CodegenCx<'a, 'tcx>, offset: Size) -> Option; @@ -244,7 +244,7 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> { /// with the inner-most trailing unsized field using the "minimal unit" /// of that field's type - this is useful for taking the address of /// that field and ensuring the struct has the right alignment. - fn llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> Type { + fn llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> &'a Type { if let layout::Abi::Scalar(ref scalar) = self.abi { // Use a different cache for scalars because pointers to DSTs // can be either fat or thin (data pointers of fat pointers). @@ -304,7 +304,7 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> { cx.lltypes.borrow_mut().insert((self.ty, variant_index), llty); - if let Some((mut llty, layout)) = defer { + if let Some((llty, layout)) = defer { let (llfields, packed) = struct_llfields(cx, layout); llty.set_struct_body(&llfields, packed) } @@ -312,7 +312,7 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> { llty } - fn immediate_llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> Type { + fn immediate_llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> &'a Type { if let layout::Abi::Scalar(ref scalar) = self.abi { if scalar.is_bool() { return Type::i1(cx); @@ -322,7 +322,7 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> { } fn scalar_llvm_type_at<'a>(&self, cx: &CodegenCx<'a, 'tcx>, - scalar: &layout::Scalar, offset: Size) -> Type { + scalar: &layout::Scalar, offset: Size) -> &'a Type { match scalar.value { layout::Int(i, _) => Type::from_integer(cx, i), layout::Float(FloatTy::F32) => Type::f32(cx), @@ -340,7 +340,7 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> { } fn scalar_pair_element_llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>, - index: usize, immediate: bool) -> Type { + index: usize, immediate: bool) -> &'a Type { // HACK(eddyb) special-case fat pointers until LLVM removes // pointee types, to avoid bitcasting every `OperandRef::deref`. match self.ty.sty { From 2dbde55395b3e868ff88af39fc4d25c70bfa31f4 Mon Sep 17 00:00:00 2001 From: Irina Popa Date: Tue, 3 Jul 2018 15:49:43 +0300 Subject: [PATCH 05/36] rustc_codegen_llvm: use safe references for Builder. --- src/librustc_codegen_llvm/builder.rs | 5 +- src/librustc_codegen_llvm/llvm/ffi.rs | 281 +++++++++++++------------- 2 files changed, 142 insertions(+), 144 deletions(-) diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index a8bfc721a9e9e..841b0add89b73 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -13,7 +13,7 @@ use llvm; use llvm::{AtomicRmwBinOp, AtomicOrdering, SynchronizationScope, AsmDialect}; use llvm::{Opcode, IntPredicate, RealPredicate, False, OperandBundleDef}; -use llvm::{ValueRef, BasicBlockRef, BuilderRef}; +use llvm::{ValueRef, BasicBlockRef}; use common::*; use type_::Type; use value::Value; @@ -32,7 +32,7 @@ use syntax_pos::Span; // All Builders must have an llfn associated with them #[must_use] pub struct Builder<'a, 'll: 'a, 'tcx: 'll> { - pub llbuilder: BuilderRef, + pub llbuilder: &'ll llvm::Builder, pub cx: &'a CodegenCx<'ll, 'tcx>, } @@ -599,7 +599,6 @@ impl Builder<'a, 'll, 'tcx> { flags: MemFlags, ) -> ValueRef { debug!("Store {:?} -> {:?} ({:?})", Value(val), Value(ptr), flags); - assert!(!self.llbuilder.is_null()); self.count_insn("store"); let ptr = self.check_store(val, ptr); unsafe { diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index 1c7988fa8d555..532fe1026a9b6 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -384,8 +384,7 @@ extern { pub type Metadata_opaque; } pub type MetadataRef = *mut Metadata_opaque; extern { pub type BasicBlock_opaque; } pub type BasicBlockRef = *mut BasicBlock_opaque; -extern { pub type Builder_opaque; } -pub type BuilderRef = *mut Builder_opaque; +extern { pub type Builder; } extern { pub type ExecutionEngine_opaque; } pub type ExecutionEngineRef = *mut ExecutionEngine_opaque; extern { pub type MemoryBuffer_opaque; } @@ -762,35 +761,35 @@ extern "C" { Count: c_uint); // Instruction builders - pub fn LLVMCreateBuilderInContext(C: &Context) -> 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); + pub fn LLVMCreateBuilderInContext(C: &Context) -> &Builder; + pub fn LLVMPositionBuilder(Builder: &Builder, Block: BasicBlockRef, Instr: ValueRef); + pub fn LLVMPositionBuilderBefore(Builder: &Builder, Instr: ValueRef); + pub fn LLVMPositionBuilderAtEnd(Builder: &Builder, Block: BasicBlockRef); + pub fn LLVMGetInsertBlock(Builder: &Builder) -> BasicBlockRef; + pub fn LLVMDisposeBuilder(Builder: &Builder); // Metadata - pub fn LLVMSetCurrentDebugLocation(Builder: BuilderRef, L: Option>); - pub fn LLVMGetCurrentDebugLocation(Builder: BuilderRef) -> ValueRef; - pub fn LLVMSetInstDebugLocation(Builder: BuilderRef, Inst: ValueRef); + pub fn LLVMSetCurrentDebugLocation(Builder: &Builder, L: Option>); + pub fn LLVMGetCurrentDebugLocation(Builder: &Builder) -> ValueRef; + pub fn LLVMSetInstDebugLocation(Builder: &Builder, 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, + pub fn LLVMBuildRetVoid(B: &Builder) -> ValueRef; + pub fn LLVMBuildRet(B: &Builder, V: ValueRef) -> ValueRef; + pub fn LLVMBuildAggregateRet(B: &Builder, RetVals: *const ValueRef, N: c_uint) -> ValueRef; + pub fn LLVMBuildBr(B: &Builder, Dest: BasicBlockRef) -> ValueRef; + pub fn LLVMBuildCondBr(B: &Builder, If: ValueRef, Then: BasicBlockRef, Else: BasicBlockRef) -> ValueRef; - pub fn LLVMBuildSwitch(B: BuilderRef, + pub fn LLVMBuildSwitch(B: &Builder, V: ValueRef, Else: BasicBlockRef, NumCases: c_uint) -> ValueRef; - pub fn LLVMBuildIndirectBr(B: BuilderRef, Addr: ValueRef, NumDests: c_uint) -> ValueRef; - pub fn LLVMRustBuildInvoke(B: BuilderRef, + pub fn LLVMBuildIndirectBr(B: &Builder, Addr: ValueRef, NumDests: c_uint) -> ValueRef; + pub fn LLVMRustBuildInvoke(B: &Builder, Fn: ValueRef, Args: *const ValueRef, NumArgs: c_uint, @@ -799,33 +798,33 @@ extern "C" { Bundle: Option>, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildLandingPad(B: BuilderRef, - Ty: &Type, + pub fn LLVMBuildLandingPad(B: &'a Builder, + Ty: &'a Type, 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 LLVMBuildResume(B: &Builder, Exn: ValueRef) -> ValueRef; + pub fn LLVMBuildUnreachable(B: &Builder) -> ValueRef; - pub fn LLVMRustBuildCleanupPad(B: BuilderRef, + pub fn LLVMRustBuildCleanupPad(B: &Builder, ParentPad: Option>, ArgCnt: c_uint, Args: *const ValueRef, Name: *const c_char) -> ValueRef; - pub fn LLVMRustBuildCleanupRet(B: BuilderRef, + pub fn LLVMRustBuildCleanupRet(B: &Builder, CleanupPad: ValueRef, UnwindBB: Option>) -> ValueRef; - pub fn LLVMRustBuildCatchPad(B: BuilderRef, + pub fn LLVMRustBuildCatchPad(B: &Builder, 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, + pub fn LLVMRustBuildCatchRet(B: &Builder, Pad: ValueRef, BB: BasicBlockRef) -> ValueRef; + pub fn LLVMRustBuildCatchSwitch(Builder: &Builder, ParentPad: Option>, BB: Option>, NumHandlers: c_uint, @@ -844,288 +843,288 @@ extern "C" { pub fn LLVMSetCleanup(LandingPad: ValueRef, Val: Bool); // Arithmetic - pub fn LLVMBuildAdd(B: BuilderRef, + pub fn LLVMBuildAdd(B: &Builder, LHS: ValueRef, RHS: ValueRef, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildNSWAdd(B: BuilderRef, + pub fn LLVMBuildNSWAdd(B: &Builder, LHS: ValueRef, RHS: ValueRef, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildNUWAdd(B: BuilderRef, + pub fn LLVMBuildNUWAdd(B: &Builder, LHS: ValueRef, RHS: ValueRef, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildFAdd(B: BuilderRef, + pub fn LLVMBuildFAdd(B: &Builder, LHS: ValueRef, RHS: ValueRef, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildSub(B: BuilderRef, + pub fn LLVMBuildSub(B: &Builder, LHS: ValueRef, RHS: ValueRef, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildNSWSub(B: BuilderRef, + pub fn LLVMBuildNSWSub(B: &Builder, LHS: ValueRef, RHS: ValueRef, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildNUWSub(B: BuilderRef, + pub fn LLVMBuildNUWSub(B: &Builder, LHS: ValueRef, RHS: ValueRef, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildFSub(B: BuilderRef, + pub fn LLVMBuildFSub(B: &Builder, LHS: ValueRef, RHS: ValueRef, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildMul(B: BuilderRef, + pub fn LLVMBuildMul(B: &Builder, LHS: ValueRef, RHS: ValueRef, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildNSWMul(B: BuilderRef, + pub fn LLVMBuildNSWMul(B: &Builder, LHS: ValueRef, RHS: ValueRef, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildNUWMul(B: BuilderRef, + pub fn LLVMBuildNUWMul(B: &Builder, LHS: ValueRef, RHS: ValueRef, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildFMul(B: BuilderRef, + pub fn LLVMBuildFMul(B: &Builder, LHS: ValueRef, RHS: ValueRef, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildUDiv(B: BuilderRef, + pub fn LLVMBuildUDiv(B: &Builder, LHS: ValueRef, RHS: ValueRef, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildExactUDiv(B: BuilderRef, + pub fn LLVMBuildExactUDiv(B: &Builder, LHS: ValueRef, RHS: ValueRef, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildSDiv(B: BuilderRef, + pub fn LLVMBuildSDiv(B: &Builder, LHS: ValueRef, RHS: ValueRef, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildExactSDiv(B: BuilderRef, + pub fn LLVMBuildExactSDiv(B: &Builder, LHS: ValueRef, RHS: ValueRef, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildFDiv(B: BuilderRef, + pub fn LLVMBuildFDiv(B: &Builder, LHS: ValueRef, RHS: ValueRef, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildURem(B: BuilderRef, + pub fn LLVMBuildURem(B: &Builder, LHS: ValueRef, RHS: ValueRef, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildSRem(B: BuilderRef, + pub fn LLVMBuildSRem(B: &Builder, LHS: ValueRef, RHS: ValueRef, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildFRem(B: BuilderRef, + pub fn LLVMBuildFRem(B: &Builder, LHS: ValueRef, RHS: ValueRef, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildShl(B: BuilderRef, + pub fn LLVMBuildShl(B: &Builder, LHS: ValueRef, RHS: ValueRef, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildLShr(B: BuilderRef, + pub fn LLVMBuildLShr(B: &Builder, LHS: ValueRef, RHS: ValueRef, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildAShr(B: BuilderRef, + pub fn LLVMBuildAShr(B: &Builder, LHS: ValueRef, RHS: ValueRef, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildAnd(B: BuilderRef, + pub fn LLVMBuildAnd(B: &Builder, LHS: ValueRef, RHS: ValueRef, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildOr(B: BuilderRef, + pub fn LLVMBuildOr(B: &Builder, LHS: ValueRef, RHS: ValueRef, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildXor(B: BuilderRef, + pub fn LLVMBuildXor(B: &Builder, LHS: ValueRef, RHS: ValueRef, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildBinOp(B: BuilderRef, + pub fn LLVMBuildBinOp(B: &Builder, 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 LLVMBuildNeg(B: &Builder, V: ValueRef, Name: *const c_char) -> ValueRef; + pub fn LLVMBuildNSWNeg(B: &Builder, V: ValueRef, Name: *const c_char) -> ValueRef; + pub fn LLVMBuildNUWNeg(B: &Builder, V: ValueRef, Name: *const c_char) -> ValueRef; + pub fn LLVMBuildFNeg(B: &Builder, V: ValueRef, Name: *const c_char) -> ValueRef; + pub fn LLVMBuildNot(B: &Builder, V: ValueRef, Name: *const c_char) -> ValueRef; pub fn LLVMRustSetHasUnsafeAlgebra(Instr: ValueRef); // Memory - pub fn LLVMBuildAlloca(B: BuilderRef, Ty: &Type, 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 LLVMBuildAlloca(B: &Builder, Ty: &Type, Name: *const c_char) -> ValueRef; + pub fn LLVMBuildFree(B: &Builder, PointerVal: ValueRef) -> ValueRef; + pub fn LLVMBuildLoad(B: &Builder, PointerVal: ValueRef, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildStore(B: BuilderRef, Val: ValueRef, Ptr: ValueRef) -> ValueRef; + pub fn LLVMBuildStore(B: &Builder, Val: ValueRef, Ptr: ValueRef) -> ValueRef; - pub fn LLVMBuildGEP(B: BuilderRef, + pub fn LLVMBuildGEP(B: &Builder, Pointer: ValueRef, Indices: *const ValueRef, NumIndices: c_uint, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildInBoundsGEP(B: BuilderRef, + pub fn LLVMBuildInBoundsGEP(B: &Builder, Pointer: ValueRef, Indices: *const ValueRef, NumIndices: c_uint, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildStructGEP(B: BuilderRef, + pub fn LLVMBuildStructGEP(B: &Builder, Pointer: ValueRef, Idx: c_uint, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildGlobalString(B: BuilderRef, + pub fn LLVMBuildGlobalString(B: &Builder, Str: *const c_char, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildGlobalStringPtr(B: BuilderRef, + pub fn LLVMBuildGlobalStringPtr(B: &Builder, Str: *const c_char, Name: *const c_char) -> ValueRef; // Casts - pub fn LLVMBuildTrunc(B: BuilderRef, + pub fn LLVMBuildTrunc(B: &'a Builder, Val: ValueRef, - DestTy: &Type, + DestTy: &'a Type, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildZExt(B: BuilderRef, + pub fn LLVMBuildZExt(B: &'a Builder, Val: ValueRef, - DestTy: &Type, + DestTy: &'a Type, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildSExt(B: BuilderRef, + pub fn LLVMBuildSExt(B: &'a Builder, Val: ValueRef, - DestTy: &Type, + DestTy: &'a Type, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildFPToUI(B: BuilderRef, + pub fn LLVMBuildFPToUI(B: &'a Builder, Val: ValueRef, - DestTy: &Type, + DestTy: &'a Type, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildFPToSI(B: BuilderRef, + pub fn LLVMBuildFPToSI(B: &'a Builder, Val: ValueRef, - DestTy: &Type, + DestTy: &'a Type, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildUIToFP(B: BuilderRef, + pub fn LLVMBuildUIToFP(B: &'a Builder, Val: ValueRef, - DestTy: &Type, + DestTy: &'a Type, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildSIToFP(B: BuilderRef, + pub fn LLVMBuildSIToFP(B: &'a Builder, Val: ValueRef, - DestTy: &Type, + DestTy: &'a Type, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildFPTrunc(B: BuilderRef, + pub fn LLVMBuildFPTrunc(B: &'a Builder, Val: ValueRef, - DestTy: &Type, + DestTy: &'a Type, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildFPExt(B: BuilderRef, + pub fn LLVMBuildFPExt(B: &'a Builder, Val: ValueRef, - DestTy: &Type, + DestTy: &'a Type, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildPtrToInt(B: BuilderRef, + pub fn LLVMBuildPtrToInt(B: &'a Builder, Val: ValueRef, - DestTy: &Type, + DestTy: &'a Type, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildIntToPtr(B: BuilderRef, + pub fn LLVMBuildIntToPtr(B: &'a Builder, Val: ValueRef, - DestTy: &Type, + DestTy: &'a Type, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildBitCast(B: BuilderRef, + pub fn LLVMBuildBitCast(B: &'a Builder, Val: ValueRef, - DestTy: &Type, + DestTy: &'a Type, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildZExtOrBitCast(B: BuilderRef, + pub fn LLVMBuildZExtOrBitCast(B: &'a Builder, Val: ValueRef, - DestTy: &Type, + DestTy: &'a Type, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildSExtOrBitCast(B: BuilderRef, + pub fn LLVMBuildSExtOrBitCast(B: &'a Builder, Val: ValueRef, - DestTy: &Type, + DestTy: &'a Type, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildTruncOrBitCast(B: BuilderRef, + pub fn LLVMBuildTruncOrBitCast(B: &'a Builder, Val: ValueRef, - DestTy: &Type, + DestTy: &'a Type, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildCast(B: BuilderRef, + pub fn LLVMBuildCast(B: &'a Builder, Op: Opcode, Val: ValueRef, - DestTy: &Type, + DestTy: &'a Type, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildPointerCast(B: BuilderRef, + pub fn LLVMBuildPointerCast(B: &'a Builder, Val: ValueRef, - DestTy: &Type, + DestTy: &'a Type, Name: *const c_char) -> ValueRef; - pub fn LLVMRustBuildIntCast(B: BuilderRef, + pub fn LLVMRustBuildIntCast(B: &'a Builder, Val: ValueRef, - DestTy: &Type, + DestTy: &'a Type, IsSized: bool) -> ValueRef; - pub fn LLVMBuildFPCast(B: BuilderRef, + pub fn LLVMBuildFPCast(B: &'a Builder, Val: ValueRef, - DestTy: &Type, + DestTy: &'a Type, Name: *const c_char) -> ValueRef; // Comparisons - pub fn LLVMBuildICmp(B: BuilderRef, + pub fn LLVMBuildICmp(B: &Builder, Op: c_uint, LHS: ValueRef, RHS: ValueRef, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildFCmp(B: BuilderRef, + pub fn LLVMBuildFCmp(B: &Builder, Op: c_uint, LHS: ValueRef, RHS: ValueRef, @@ -1133,119 +1132,119 @@ extern "C" { -> ValueRef; // Miscellaneous instructions - pub fn LLVMBuildPhi(B: BuilderRef, Ty: &Type, Name: *const c_char) -> ValueRef; - pub fn LLVMRustBuildCall(B: BuilderRef, + pub fn LLVMBuildPhi(B: &Builder, Ty: &Type, Name: *const c_char) -> ValueRef; + pub fn LLVMRustBuildCall(B: &Builder, Fn: ValueRef, Args: *const ValueRef, NumArgs: c_uint, Bundle: Option>, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildSelect(B: BuilderRef, + pub fn LLVMBuildSelect(B: &Builder, If: ValueRef, Then: ValueRef, Else: ValueRef, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildVAArg(B: BuilderRef, + pub fn LLVMBuildVAArg(B: &'a Builder, list: ValueRef, - Ty: &Type, + Ty: &'a Type, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildExtractElement(B: BuilderRef, + pub fn LLVMBuildExtractElement(B: &Builder, VecVal: ValueRef, Index: ValueRef, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildInsertElement(B: BuilderRef, + pub fn LLVMBuildInsertElement(B: &Builder, VecVal: ValueRef, EltVal: ValueRef, Index: ValueRef, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildShuffleVector(B: BuilderRef, + pub fn LLVMBuildShuffleVector(B: &Builder, V1: ValueRef, V2: ValueRef, Mask: ValueRef, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildExtractValue(B: BuilderRef, + pub fn LLVMBuildExtractValue(B: &Builder, AggVal: ValueRef, Index: c_uint, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildInsertValue(B: BuilderRef, + pub fn LLVMBuildInsertValue(B: &Builder, AggVal: ValueRef, EltVal: ValueRef, Index: c_uint, Name: *const c_char) -> ValueRef; - pub fn LLVMRustBuildVectorReduceFAdd(B: BuilderRef, + pub fn LLVMRustBuildVectorReduceFAdd(B: &Builder, Acc: ValueRef, Src: ValueRef) -> ValueRef; - pub fn LLVMRustBuildVectorReduceFMul(B: BuilderRef, + pub fn LLVMRustBuildVectorReduceFMul(B: &Builder, Acc: ValueRef, Src: ValueRef) -> ValueRef; - pub fn LLVMRustBuildVectorReduceAdd(B: BuilderRef, + pub fn LLVMRustBuildVectorReduceAdd(B: &Builder, Src: ValueRef) -> ValueRef; - pub fn LLVMRustBuildVectorReduceMul(B: BuilderRef, + pub fn LLVMRustBuildVectorReduceMul(B: &Builder, Src: ValueRef) -> ValueRef; - pub fn LLVMRustBuildVectorReduceAnd(B: BuilderRef, + pub fn LLVMRustBuildVectorReduceAnd(B: &Builder, Src: ValueRef) -> ValueRef; - pub fn LLVMRustBuildVectorReduceOr(B: BuilderRef, + pub fn LLVMRustBuildVectorReduceOr(B: &Builder, Src: ValueRef) -> ValueRef; - pub fn LLVMRustBuildVectorReduceXor(B: BuilderRef, + pub fn LLVMRustBuildVectorReduceXor(B: &Builder, Src: ValueRef) -> ValueRef; - pub fn LLVMRustBuildVectorReduceMin(B: BuilderRef, + pub fn LLVMRustBuildVectorReduceMin(B: &Builder, Src: ValueRef, IsSigned: bool) -> ValueRef; - pub fn LLVMRustBuildVectorReduceMax(B: BuilderRef, + pub fn LLVMRustBuildVectorReduceMax(B: &Builder, Src: ValueRef, IsSigned: bool) -> ValueRef; - pub fn LLVMRustBuildVectorReduceFMin(B: BuilderRef, + pub fn LLVMRustBuildVectorReduceFMin(B: &Builder, Src: ValueRef, IsNaN: bool) -> ValueRef; - pub fn LLVMRustBuildVectorReduceFMax(B: BuilderRef, + pub fn LLVMRustBuildVectorReduceFMax(B: &Builder, 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 LLVMRustBuildMinNum(B: &Builder, LHS: ValueRef, LHS: ValueRef) -> ValueRef; + pub fn LLVMRustBuildMaxNum(B: &Builder, 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, + pub fn LLVMBuildIsNull(B: &Builder, Val: ValueRef, Name: *const c_char) -> ValueRef; + pub fn LLVMBuildIsNotNull(B: &Builder, Val: ValueRef, Name: *const c_char) -> ValueRef; + pub fn LLVMBuildPtrDiff(B: &Builder, LHS: ValueRef, RHS: ValueRef, Name: *const c_char) -> ValueRef; // Atomic Operations - pub fn LLVMRustBuildAtomicLoad(B: BuilderRef, + pub fn LLVMRustBuildAtomicLoad(B: &Builder, PointerVal: ValueRef, Name: *const c_char, Order: AtomicOrdering) -> ValueRef; - pub fn LLVMRustBuildAtomicStore(B: BuilderRef, + pub fn LLVMRustBuildAtomicStore(B: &Builder, Val: ValueRef, Ptr: ValueRef, Order: AtomicOrdering) -> ValueRef; - pub fn LLVMRustBuildAtomicCmpXchg(B: BuilderRef, + pub fn LLVMRustBuildAtomicCmpXchg(B: &Builder, LHS: ValueRef, CMP: ValueRef, RHS: ValueRef, @@ -1254,7 +1253,7 @@ extern "C" { Weak: Bool) -> ValueRef; - pub fn LLVMBuildAtomicRMW(B: BuilderRef, + pub fn LLVMBuildAtomicRMW(B: &Builder, Op: AtomicRmwBinOp, LHS: ValueRef, RHS: ValueRef, @@ -1262,7 +1261,7 @@ extern "C" { SingleThreaded: Bool) -> ValueRef; - pub fn LLVMRustBuildAtomicFence(B: BuilderRef, + pub fn LLVMRustBuildAtomicFence(B: &Builder, Order: AtomicOrdering, Scope: SynchronizationScope); @@ -1709,7 +1708,7 @@ extern "C" { -> OperandBundleDefRef; pub fn LLVMRustFreeOperandBundleDef(Bundle: OperandBundleDefRef); - pub fn LLVMRustPositionBuilderAtStart(B: BuilderRef, BB: BasicBlockRef); + pub fn LLVMRustPositionBuilderAtStart(B: &Builder, BB: BasicBlockRef); pub fn LLVMRustSetComdat(M: &Module, V: ValueRef, Name: *const c_char); pub fn LLVMRustUnsetComdat(V: ValueRef); From 6d0d82ce10bfbdb44aab9a2f120b236ebc7e0175 Mon Sep 17 00:00:00 2001 From: Irina Popa Date: Tue, 3 Jul 2018 16:02:38 +0300 Subject: [PATCH 06/36] rustc_codegen_llvm: use safe references for DIBuilder. --- src/librustc_codegen_llvm/debuginfo/mod.rs | 4 +- src/librustc_codegen_llvm/debuginfo/utils.rs | 6 +-- src/librustc_codegen_llvm/llvm/ffi.rs | 57 ++++++++++---------- 3 files changed, 33 insertions(+), 34 deletions(-) diff --git a/src/librustc_codegen_llvm/debuginfo/mod.rs b/src/librustc_codegen_llvm/debuginfo/mod.rs index 3336e46ea797d..43534b8ec2e03 100644 --- a/src/librustc_codegen_llvm/debuginfo/mod.rs +++ b/src/librustc_codegen_llvm/debuginfo/mod.rs @@ -22,7 +22,7 @@ use self::source_loc::InternalDebugLocation::{self, UnknownLocation}; use llvm; use llvm::ValueRef; -use llvm::debuginfo::{DIFile, DIType, DIScope, DIBuilderRef, DISubprogram, DIArray, DIFlags}; +use llvm::debuginfo::{DIFile, DIType, DIScope, DIBuilder, DISubprogram, DIArray, DIFlags}; use rustc::hir::CodegenFnAttrFlags; use rustc::hir::def_id::{DefId, CrateNum}; use rustc::ty::subst::{Substs, UnpackedKind}; @@ -70,7 +70,7 @@ const DW_TAG_arg_variable: c_uint = 0x101; pub struct CrateDebugContext<'a, 'tcx> { llcontext: &'a llvm::Context, llmod: &'a llvm::Module, - builder: DIBuilderRef, + builder: &'a DIBuilder, created_files: RefCell>, created_enum_disr_types: RefCell>, diff --git a/src/librustc_codegen_llvm/debuginfo/utils.rs b/src/librustc_codegen_llvm/debuginfo/utils.rs index 69d457f218832..602a64ae3b33a 100644 --- a/src/librustc_codegen_llvm/debuginfo/utils.rs +++ b/src/librustc_codegen_llvm/debuginfo/utils.rs @@ -17,7 +17,7 @@ use rustc::hir::def_id::DefId; use rustc::ty::DefIdTree; use llvm; -use llvm::debuginfo::{DIScope, DIBuilderRef, DIDescriptor_opaque, DIArray}; +use llvm::debuginfo::{DIScope, DIBuilder, DIDescriptor_opaque, DIArray}; use common::{CodegenCx}; use std::ptr::NonNull; @@ -37,7 +37,7 @@ pub fn is_node_local_to_unit(cx: &CodegenCx, def_id: DefId) -> bool } #[allow(non_snake_case)] -pub fn create_DIArray(builder: DIBuilderRef, arr: &[Option>]) -> DIArray { +pub fn create_DIArray(builder: &DIBuilder, arr: &[Option>]) -> DIArray { return unsafe { llvm::LLVMRustDIBuilderGetOrCreateArray(builder, arr.as_ptr(), arr.len() as u32) }; @@ -55,7 +55,7 @@ pub fn debug_context(cx: &'a CodegenCx<'ll, 'tcx>) -> &'a CrateDebugContext<'a, #[inline] #[allow(non_snake_case)] -pub fn DIB(cx: &CodegenCx) -> DIBuilderRef { +pub fn DIB(cx: &CodegenCx<'ll, '_>) -> &'ll DIBuilder { cx.dbg_cx.as_ref().unwrap().builder } diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index 532fe1026a9b6..b202a1bf2f70e 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -15,7 +15,7 @@ // https://reviews.llvm.org/D26769 use super::debuginfo::{ - DIBuilderRef, DIDescriptor_opaque, DIDescriptor, DIFile, DILexicalBlock, DISubprogram, DIType_opaque, + DIBuilder, DIDescriptor_opaque, DIDescriptor, DIFile, DILexicalBlock, DISubprogram, DIType_opaque, DIType, DIBasicType, DIDerivedType, DICompositeType, DIScope_opaque, DIScope, DIVariable, DIGlobalVariable, DIArray_opaque, DIArray, DISubrange, DITemplateTypeParameter, DIEnumerator, DINameSpace, DIFlags, @@ -433,8 +433,7 @@ pub type InlineAsmDiagHandler = unsafe extern "C" fn(SMDiagnosticRef, *const c_v pub mod debuginfo { use super::Metadata_opaque; - extern { pub type DIBuilder_opaque; } - pub type DIBuilderRef = *mut DIBuilder_opaque; + extern { pub type DIBuilder; } pub type DIDescriptor_opaque = Metadata_opaque; pub type DIDescriptor = *mut DIDescriptor_opaque; @@ -1369,13 +1368,13 @@ extern "C" { pub fn LLVMRustMetadataAsValue(C: &Context, MD: MetadataRef) -> ValueRef; - pub fn LLVMRustDIBuilderCreate(M: &Module) -> DIBuilderRef; + pub fn LLVMRustDIBuilderCreate(M: &Module) -> &DIBuilder; - pub fn LLVMRustDIBuilderDispose(Builder: DIBuilderRef); + pub fn LLVMRustDIBuilderDispose(Builder: &DIBuilder); - pub fn LLVMRustDIBuilderFinalize(Builder: DIBuilderRef); + pub fn LLVMRustDIBuilderFinalize(Builder: &DIBuilder); - pub fn LLVMRustDIBuilderCreateCompileUnit(Builder: DIBuilderRef, + pub fn LLVMRustDIBuilderCreateCompileUnit(Builder: &DIBuilder, Lang: c_uint, File: DIFile, Producer: *const c_char, @@ -1385,17 +1384,17 @@ extern "C" { SplitName: *const c_char) -> DIDescriptor; - pub fn LLVMRustDIBuilderCreateFile(Builder: DIBuilderRef, + pub fn LLVMRustDIBuilderCreateFile(Builder: &DIBuilder, Filename: *const c_char, Directory: *const c_char) -> DIFile; - pub fn LLVMRustDIBuilderCreateSubroutineType(Builder: DIBuilderRef, + pub fn LLVMRustDIBuilderCreateSubroutineType(Builder: &DIBuilder, File: DIFile, ParameterTypes: DIArray) -> DICompositeType; - pub fn LLVMRustDIBuilderCreateFunction(Builder: DIBuilderRef, + pub fn LLVMRustDIBuilderCreateFunction(Builder: &DIBuilder, Scope: DIDescriptor, Name: *const c_char, LinkageName: *const c_char, @@ -1412,21 +1411,21 @@ extern "C" { Decl: Option>) -> DISubprogram; - pub fn LLVMRustDIBuilderCreateBasicType(Builder: DIBuilderRef, + pub fn LLVMRustDIBuilderCreateBasicType(Builder: &DIBuilder, Name: *const c_char, SizeInBits: u64, AlignInBits: u32, Encoding: c_uint) -> DIBasicType; - pub fn LLVMRustDIBuilderCreatePointerType(Builder: DIBuilderRef, + pub fn LLVMRustDIBuilderCreatePointerType(Builder: &DIBuilder, PointeeTy: DIType, SizeInBits: u64, AlignInBits: u32, Name: *const c_char) -> DIDerivedType; - pub fn LLVMRustDIBuilderCreateStructType(Builder: DIBuilderRef, + pub fn LLVMRustDIBuilderCreateStructType(Builder: &DIBuilder, Scope: Option>, Name: *const c_char, File: DIFile, @@ -1441,7 +1440,7 @@ extern "C" { UniqueId: *const c_char) -> DICompositeType; - pub fn LLVMRustDIBuilderCreateMemberType(Builder: DIBuilderRef, + pub fn LLVMRustDIBuilderCreateMemberType(Builder: &DIBuilder, Scope: DIDescriptor, Name: *const c_char, File: DIFile, @@ -1453,19 +1452,19 @@ extern "C" { Ty: DIType) -> DIDerivedType; - pub fn LLVMRustDIBuilderCreateLexicalBlock(Builder: DIBuilderRef, + pub fn LLVMRustDIBuilderCreateLexicalBlock(Builder: &DIBuilder, Scope: DIScope, File: DIFile, Line: c_uint, Col: c_uint) -> DILexicalBlock; - pub fn LLVMRustDIBuilderCreateLexicalBlockFile(Builder: DIBuilderRef, + pub fn LLVMRustDIBuilderCreateLexicalBlockFile(Builder: &DIBuilder, Scope: DIScope, File: DIFile) -> DILexicalBlock; - pub fn LLVMRustDIBuilderCreateStaticVariable(Builder: DIBuilderRef, + pub fn LLVMRustDIBuilderCreateStaticVariable(Builder: &DIBuilder, Context: Option>, Name: *const c_char, LinkageName: *const c_char, @@ -1478,7 +1477,7 @@ extern "C" { AlignInBits: u32) -> DIGlobalVariable; - pub fn LLVMRustDIBuilderCreateVariable(Builder: DIBuilderRef, + pub fn LLVMRustDIBuilderCreateVariable(Builder: &DIBuilder, Tag: c_uint, Scope: DIDescriptor, Name: *const c_char, @@ -1491,31 +1490,31 @@ extern "C" { AlignInBits: u32) -> DIVariable; - pub fn LLVMRustDIBuilderCreateArrayType(Builder: DIBuilderRef, + pub fn LLVMRustDIBuilderCreateArrayType(Builder: &DIBuilder, Size: u64, AlignInBits: u32, Ty: DIType, Subscripts: DIArray) -> DIType; - pub fn LLVMRustDIBuilderCreateVectorType(Builder: DIBuilderRef, + pub fn LLVMRustDIBuilderCreateVectorType(Builder: &DIBuilder, Size: u64, AlignInBits: u32, Ty: DIType, Subscripts: DIArray) -> DIType; - pub fn LLVMRustDIBuilderGetOrCreateSubrange(Builder: DIBuilderRef, + pub fn LLVMRustDIBuilderGetOrCreateSubrange(Builder: &DIBuilder, Lo: i64, Count: i64) -> DISubrange; - pub fn LLVMRustDIBuilderGetOrCreateArray(Builder: DIBuilderRef, + pub fn LLVMRustDIBuilderGetOrCreateArray(Builder: &DIBuilder, Ptr: *const Option>, Count: c_uint) -> DIArray; - pub fn LLVMRustDIBuilderInsertDeclareAtEnd(Builder: DIBuilderRef, + pub fn LLVMRustDIBuilderInsertDeclareAtEnd(Builder: &DIBuilder, Val: ValueRef, VarInfo: DIVariable, AddrOps: *const i64, @@ -1524,12 +1523,12 @@ extern "C" { InsertAtEnd: BasicBlockRef) -> ValueRef; - pub fn LLVMRustDIBuilderCreateEnumerator(Builder: DIBuilderRef, + pub fn LLVMRustDIBuilderCreateEnumerator(Builder: &DIBuilder, Name: *const c_char, Val: u64) -> DIEnumerator; - pub fn LLVMRustDIBuilderCreateEnumerationType(Builder: DIBuilderRef, + pub fn LLVMRustDIBuilderCreateEnumerationType(Builder: &DIBuilder, Scope: DIScope, Name: *const c_char, File: DIFile, @@ -1540,7 +1539,7 @@ extern "C" { ClassType: DIType) -> DIType; - pub fn LLVMRustDIBuilderCreateUnionType(Builder: DIBuilderRef, + pub fn LLVMRustDIBuilderCreateUnionType(Builder: &DIBuilder, Scope: DIScope, Name: *const c_char, File: DIFile, @@ -1555,7 +1554,7 @@ extern "C" { pub fn LLVMSetUnnamedAddr(GlobalVar: ValueRef, UnnamedAddr: Bool); - pub fn LLVMRustDIBuilderCreateTemplateTypeParameter(Builder: DIBuilderRef, + pub fn LLVMRustDIBuilderCreateTemplateTypeParameter(Builder: &DIBuilder, Scope: Option>, Name: *const c_char, Ty: DIType, @@ -1565,13 +1564,13 @@ extern "C" { -> DITemplateTypeParameter; - pub fn LLVMRustDIBuilderCreateNameSpace(Builder: DIBuilderRef, + pub fn LLVMRustDIBuilderCreateNameSpace(Builder: &DIBuilder, Scope: Option>, Name: *const c_char, File: DIFile, LineNo: c_uint) -> DINameSpace; - pub fn LLVMRustDICompositeTypeSetTypeArray(Builder: DIBuilderRef, + pub fn LLVMRustDICompositeTypeSetTypeArray(Builder: &DIBuilder, CompositeType: DIType, TypeArray: DIArray); From eed48f560fa44e60cec89df894018dc4599730d0 Mon Sep 17 00:00:00 2001 From: Irina Popa Date: Wed, 4 Jul 2018 16:36:49 +0300 Subject: [PATCH 07/36] rustc_codegen_llvm: use safe references for Metadata and DI*. --- src/librustc_codegen_llvm/base.rs | 6 +- .../debuginfo/create_scope_map.rs | 27 +- .../debuginfo/metadata.rs | 387 ++++++++++-------- src/librustc_codegen_llvm/debuginfo/mod.rs | 79 ++-- .../debuginfo/namespace.rs | 9 +- .../debuginfo/source_loc.rs | 21 +- src/librustc_codegen_llvm/debuginfo/utils.rs | 9 +- src/librustc_codegen_llvm/intrinsic.rs | 4 +- src/librustc_codegen_llvm/llvm/ffi.rs | 209 +++++----- src/librustc_codegen_llvm/llvm/mod.rs | 1 - src/librustc_codegen_llvm/mir/mod.rs | 27 +- src/librustc_codegen_llvm/type_.rs | 9 +- 12 files changed, 411 insertions(+), 377 deletions(-) diff --git a/src/librustc_codegen_llvm/base.rs b/src/librustc_codegen_llvm/base.rs index 21b22b387c9f3..f6fdf18dd94df 100644 --- a/src/librustc_codegen_llvm/base.rs +++ b/src/librustc_codegen_llvm/base.rs @@ -31,7 +31,7 @@ use super::ModuleKind; use abi; use back::link; use back::write::{self, OngoingCodegen}; -use llvm::{ValueRef, Vector, get_param}; +use llvm::{TypeKind, ValueRef, get_param}; use llvm; use metadata; use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; @@ -349,10 +349,10 @@ fn cast_shift_rhs<'ll, F, G>(op: hir::BinOpKind, if op.is_shift() { let mut rhs_llty = val_ty(rhs); let mut lhs_llty = val_ty(lhs); - if rhs_llty.kind() == Vector { + if rhs_llty.kind() == TypeKind::Vector { rhs_llty = rhs_llty.element_type() } - if lhs_llty.kind() == Vector { + if lhs_llty.kind() == TypeKind::Vector { lhs_llty = lhs_llty.element_type() } let rhs_sz = rhs_llty.int_width(); diff --git a/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs b/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs index dc92363a83354..4d6744c516cdf 100644 --- a/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs +++ b/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs @@ -13,10 +13,9 @@ use super::metadata::file_metadata; use super::utils::{DIB, span_start}; use llvm; -use llvm::debuginfo::DIScope_opaque; +use llvm::debuginfo::DIScope; use common::CodegenCx; use rustc::mir::{Mir, SourceScope}; -use std::ptr::NonNull; use libc::c_uint; @@ -28,15 +27,15 @@ use rustc_data_structures::indexed_vec::{Idx, IndexVec}; use syntax_pos::BytePos; #[derive(Clone, Copy, Debug)] -pub struct MirDebugScope { - pub scope_metadata: Option>, +pub struct MirDebugScope<'ll> { + pub scope_metadata: Option<&'ll DIScope>, // Start and end offsets of the file to which this DIScope belongs. // These are used to quickly determine whether some span refers to the same file. pub file_start_pos: BytePos, pub file_end_pos: BytePos, } -impl MirDebugScope { +impl MirDebugScope<'ll> { pub fn is_valid(&self) -> bool { !self.scope_metadata.is_none() } @@ -44,8 +43,8 @@ impl MirDebugScope { /// Produce DIScope DIEs for each MIR Scope which has variables defined in it. /// If debuginfo is disabled, the returned vector is empty. -pub fn create_mir_scopes(cx: &CodegenCx, mir: &Mir, debug_context: &FunctionDebugContext) - -> IndexVec { +pub fn create_mir_scopes(cx: &CodegenCx<'ll, '_>, mir: &Mir, debug_context: &FunctionDebugContext<'ll>) + -> IndexVec> { let null_scope = MirDebugScope { scope_metadata: None, file_start_pos: BytePos(0), @@ -77,12 +76,12 @@ pub fn create_mir_scopes(cx: &CodegenCx, mir: &Mir, debug_context: &FunctionDebu scopes } -fn make_mir_scope(cx: &CodegenCx, +fn make_mir_scope(cx: &CodegenCx<'ll, '_>, mir: &Mir, has_variables: &BitVector, - debug_context: &FunctionDebugContextData, + debug_context: &FunctionDebugContextData<'ll>, scope: SourceScope, - scopes: &mut IndexVec) { + scopes: &mut IndexVec>) { if scopes[scope].is_valid() { return; } @@ -95,7 +94,7 @@ fn make_mir_scope(cx: &CodegenCx, // The root is the function itself. let loc = span_start(cx, mir.span); scopes[scope] = MirDebugScope { - scope_metadata: NonNull::new(debug_context.fn_metadata), + scope_metadata: Some(debug_context.fn_metadata), file_start_pos: loc.file.start_pos, file_end_pos: loc.file.end_pos, }; @@ -109,7 +108,7 @@ fn make_mir_scope(cx: &CodegenCx, // However, we don't skip creating a nested scope if // our parent is the root, because we might want to // put arguments in the root and not have shadowing. - if parent_scope.scope_metadata.unwrap().as_ptr() != debug_context.fn_metadata { + if parent_scope.scope_metadata.unwrap() != debug_context.fn_metadata { scopes[scope] = parent_scope; return; } @@ -121,9 +120,9 @@ fn make_mir_scope(cx: &CodegenCx, debug_context.defining_crate); let scope_metadata = unsafe { - NonNull::new(llvm::LLVMRustDIBuilderCreateLexicalBlock( + Some(llvm::LLVMRustDIBuilderCreateLexicalBlock( DIB(cx), - parent_scope.scope_metadata.unwrap().as_ptr(), + parent_scope.scope_metadata.unwrap(), file_metadata, loc.line as c_uint, loc.col.to_usize() as c_uint)) diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs index e7a6dc4522214..ae2e350dc651c 100644 --- a/src/librustc_codegen_llvm/debuginfo/metadata.rs +++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs @@ -20,7 +20,7 @@ use super::{CrateDebugContext}; use abi; use llvm::{self, ValueRef}; -use llvm::debuginfo::{DIType, DIFile, DIScope_opaque, DIScope, DIDescriptor, +use llvm::debuginfo::{DIType, DIFile, DIScope, DIDescriptor, DICompositeType, DILexicalBlock, DIFlags}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; @@ -38,15 +38,34 @@ use rustc::util::common::path2cstr; use libc::{c_uint, c_longlong}; use std::ffi::CString; -use std::fmt::Write; +use std::fmt::{self, Write}; +use std::hash::{Hash, Hasher}; use std::iter; use std::ptr; -use std::ptr::NonNull; use std::path::{Path, PathBuf}; use syntax::ast; use syntax::symbol::{Interner, InternedString, Symbol}; use syntax_pos::{self, Span, FileName}; +impl PartialEq for llvm::Metadata { + fn eq(&self, other: &Self) -> bool { + self as *const _ == other as *const _ + } +} + +impl Eq for llvm::Metadata {} + +impl Hash for llvm::Metadata { + fn hash(&self, hasher: &mut H) { + (self as *const Self).hash(hasher); + } +} + +impl fmt::Debug for llvm::Metadata { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + (self as *const Self).fmt(f) + } +} // From DWARF 5. // See http://www.dwarfstd.org/ShowIssue.php?issue=140129.1 @@ -65,7 +84,7 @@ const DW_ATE_unsigned_char: c_uint = 0x08; pub const UNKNOWN_LINE_NUMBER: c_uint = 0; pub const UNKNOWN_COLUMN_NUMBER: c_uint = 0; -pub const NO_SCOPE_METADATA: Option> = None; +pub const NO_SCOPE_METADATA: Option<&DIScope> = None; #[derive(Copy, Debug, Hash, Eq, PartialEq, Clone)] pub struct UniqueTypeId(ast::Name); @@ -74,19 +93,19 @@ pub struct UniqueTypeId(ast::Name); // created so far. The metadata nodes are indexed by UniqueTypeId, and, for // faster lookup, also by Ty. The TypeMap is responsible for creating // UniqueTypeIds. -pub struct TypeMap<'tcx> { +pub struct TypeMap<'ll, 'tcx> { // The UniqueTypeIds created so far unique_id_interner: Interner, // A map from UniqueTypeId to debuginfo metadata for that type. This is a 1:1 mapping. - unique_id_to_metadata: FxHashMap, + unique_id_to_metadata: FxHashMap, // A map from types to debuginfo metadata. This is a N:1 mapping. - type_to_metadata: FxHashMap, DIType>, + type_to_metadata: FxHashMap, &'ll DIType>, // A map from types to UniqueTypeId. This is a N:1 mapping. type_to_unique_id: FxHashMap, UniqueTypeId> } -impl<'tcx> TypeMap<'tcx> { - pub fn new() -> TypeMap<'tcx> { +impl TypeMap<'ll, 'tcx> { + pub fn new() -> Self { TypeMap { unique_id_interner: Interner::new(), type_to_metadata: FxHashMap(), @@ -97,9 +116,11 @@ impl<'tcx> TypeMap<'tcx> { // Adds a Ty to metadata mapping to the TypeMap. The method will fail if // the mapping already exists. - fn register_type_with_metadata<'a>(&mut self, - type_: Ty<'tcx>, - metadata: DIType) { + fn register_type_with_metadata( + &mut self, + type_: Ty<'tcx>, + metadata: &'ll DIType, + ) { if self.type_to_metadata.insert(type_, metadata).is_some() { bug!("Type metadata for Ty '{}' is already in the TypeMap!", type_); } @@ -107,20 +128,22 @@ impl<'tcx> TypeMap<'tcx> { // Adds a UniqueTypeId to metadata mapping to the TypeMap. The method will // fail if the mapping already exists. - fn register_unique_id_with_metadata(&mut self, - unique_type_id: UniqueTypeId, - metadata: DIType) { + fn register_unique_id_with_metadata( + &mut self, + unique_type_id: UniqueTypeId, + metadata: &'ll DIType, + ) { if self.unique_id_to_metadata.insert(unique_type_id, metadata).is_some() { bug!("Type metadata for unique id '{}' is already in the TypeMap!", self.get_unique_type_id_as_string(unique_type_id)); } } - fn find_metadata_for_type(&self, type_: Ty<'tcx>) -> Option { + fn find_metadata_for_type(&self, type_: Ty<'tcx>) -> Option<&'ll DIType> { self.type_to_metadata.get(&type_).cloned() } - fn find_metadata_for_unique_id(&self, unique_type_id: UniqueTypeId) -> Option { + fn find_metadata_for_unique_id(&self, unique_type_id: UniqueTypeId) -> Option<&'ll DIType> { self.unique_id_to_metadata.get(&unique_type_id).cloned() } @@ -182,23 +205,23 @@ impl<'tcx> TypeMap<'tcx> { // needed to generate the missing parts of the description. See the // documentation section on Recursive Types at the top of this file for more // information. -enum RecursiveTypeDescription<'tcx> { +enum RecursiveTypeDescription<'ll, 'tcx> { UnfinishedMetadata { unfinished_type: Ty<'tcx>, unique_type_id: UniqueTypeId, - metadata_stub: DICompositeType, - member_description_factory: MemberDescriptionFactory<'tcx>, + metadata_stub: &'ll DICompositeType, + member_description_factory: MemberDescriptionFactory<'ll, 'tcx>, }, - FinalMetadata(DICompositeType) + FinalMetadata(&'ll DICompositeType) } -fn create_and_register_recursive_type_forward_declaration<'a, 'tcx>( - cx: &CodegenCx<'a, 'tcx>, +fn create_and_register_recursive_type_forward_declaration( + cx: &CodegenCx<'ll, 'tcx>, unfinished_type: Ty<'tcx>, unique_type_id: UniqueTypeId, - metadata_stub: DICompositeType, - member_description_factory: MemberDescriptionFactory<'tcx>) - -> RecursiveTypeDescription<'tcx> { + metadata_stub: &'ll DICompositeType, + member_description_factory: MemberDescriptionFactory<'ll, 'tcx>, +) -> RecursiveTypeDescription<'ll, 'tcx> { // Insert the stub into the TypeMap in order to allow for recursive references let mut type_map = debug_context(cx).type_map.borrow_mut(); @@ -213,11 +236,11 @@ fn create_and_register_recursive_type_forward_declaration<'a, 'tcx>( } } -impl<'tcx> RecursiveTypeDescription<'tcx> { +impl RecursiveTypeDescription<'ll, 'tcx> { // Finishes up the description of the type in question (mostly by providing // descriptions of the fields of the given type) and returns the final type // metadata. - fn finalize<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> MetadataCreationResult { + fn finalize(&self, cx: &CodegenCx<'ll, 'tcx>) -> MetadataCreationResult<'ll> { match *self { FinalMetadata(metadata) => MetadataCreationResult::new(metadata, false), UnfinishedMetadata { @@ -269,12 +292,13 @@ macro_rules! return_if_metadata_created_in_meantime { ) } -fn fixed_vec_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, - unique_type_id: UniqueTypeId, - array_or_slice_type: Ty<'tcx>, - element_type: Ty<'tcx>, - span: Span) - -> MetadataCreationResult { +fn fixed_vec_metadata( + cx: &CodegenCx<'ll, 'tcx>, + unique_type_id: UniqueTypeId, + array_or_slice_type: Ty<'tcx>, + element_type: Ty<'tcx>, + span: Span, +) -> MetadataCreationResult<'ll> { let element_type_metadata = type_metadata(cx, element_type, span); return_if_metadata_created_in_meantime!(cx, unique_type_id); @@ -289,7 +313,7 @@ fn fixed_vec_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, }; let subrange = unsafe { - NonNull::new(llvm::LLVMRustDIBuilderGetOrCreateSubrange(DIB(cx), 0, upper_bound)) + Some(llvm::LLVMRustDIBuilderGetOrCreateSubrange(DIB(cx), 0, upper_bound)) }; let subscripts = create_DIArray(DIB(cx), &[subrange]); @@ -305,12 +329,13 @@ fn fixed_vec_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, return MetadataCreationResult::new(metadata, false); } -fn vec_slice_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, - slice_ptr_type: Ty<'tcx>, - element_type: Ty<'tcx>, - unique_type_id: UniqueTypeId, - span: Span) - -> MetadataCreationResult { +fn vec_slice_metadata( + cx: &CodegenCx<'ll, 'tcx>, + slice_ptr_type: Ty<'tcx>, + element_type: Ty<'tcx>, + unique_type_id: UniqueTypeId, + span: Span, +) -> MetadataCreationResult<'ll> { let data_ptr_type = cx.tcx.mk_imm_ptr(element_type); let data_ptr_metadata = type_metadata(cx, data_ptr_type, span); @@ -354,12 +379,12 @@ fn vec_slice_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, MetadataCreationResult::new(metadata, false) } -fn subroutine_type_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, - unique_type_id: UniqueTypeId, - signature: ty::PolyFnSig<'tcx>, - span: Span) - -> MetadataCreationResult -{ +fn subroutine_type_metadata( + cx: &CodegenCx<'ll, 'tcx>, + unique_type_id: UniqueTypeId, + signature: ty::PolyFnSig<'tcx>, + span: Span, +) -> MetadataCreationResult<'ll> { let signature = cx.tcx.normalize_erasing_late_bound_regions( ty::ParamEnv::reveal_all(), &signature, @@ -369,12 +394,12 @@ fn subroutine_type_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, // return type match signature.output().sty { ty::TyTuple(ref tys) if tys.is_empty() => None, - _ => NonNull::new(type_metadata(cx, signature.output(), span)) + _ => Some(type_metadata(cx, signature.output(), span)) } ).chain( // regular arguments signature.inputs().iter().map(|argument_type| { - NonNull::new(type_metadata(cx, argument_type, span)) + Some(type_metadata(cx, argument_type, span)) }) ).collect(); @@ -396,11 +421,12 @@ fn subroutine_type_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, // trait_type should be the actual trait (e.g., Trait). Where the trait is part // of a DST struct, there is no trait_object_type and the results of this // function will be a little bit weird. -fn trait_pointer_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, - trait_type: Ty<'tcx>, - trait_object_type: Option>, - unique_type_id: UniqueTypeId) - -> DIType { +fn trait_pointer_metadata( + cx: &CodegenCx<'ll, 'tcx>, + trait_type: Ty<'tcx>, + trait_object_type: Option>, + unique_type_id: UniqueTypeId, +) -> &'ll DIType { // The implementation provided here is a stub. It makes sure that the trait // type is assigned the correct name, size, namespace, and source location. // But it does not describe the trait's methods. @@ -408,7 +434,7 @@ fn trait_pointer_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, let containing_scope = match trait_type.sty { ty::TyDynamic(ref data, ..) => if let Some(principal) = data.principal() { let def_id = principal.def_id(); - NonNull::new(get_namespace_for_item(cx, def_id)) + Some(get_namespace_for_item(cx, def_id)) } else { NO_SCOPE_METADATA }, @@ -463,10 +489,11 @@ fn trait_pointer_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, syntax_pos::DUMMY_SP) } -pub fn type_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, - t: Ty<'tcx>, - usage_site_span: Span) - -> DIType { +pub fn type_metadata( + cx: &CodegenCx<'ll, 'tcx>, + t: Ty<'tcx>, + usage_site_span: Span, +) -> &'ll DIType { // Get the unique type id of this type. let unique_type_id = { let mut type_map = debug_context(cx).type_map.borrow_mut(); @@ -683,9 +710,9 @@ pub fn type_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, metadata } -pub fn file_metadata(cx: &CodegenCx, +pub fn file_metadata(cx: &CodegenCx<'ll, '_>, file_name: &FileName, - defining_crate: CrateNum) -> DIFile { + defining_crate: CrateNum) -> &'ll DIFile { debug!("file_metadata: file_name: {}, defining_crate: {}", file_name, defining_crate); @@ -701,14 +728,14 @@ pub fn file_metadata(cx: &CodegenCx, file_metadata_raw(cx, &file_name.to_string(), &directory.to_string_lossy()) } -pub fn unknown_file_metadata(cx: &CodegenCx) -> DIFile { +pub fn unknown_file_metadata(cx: &CodegenCx<'ll, '_>) -> &'ll DIFile { file_metadata_raw(cx, "", "") } -fn file_metadata_raw(cx: &CodegenCx, +fn file_metadata_raw(cx: &CodegenCx<'ll, '_>, file_name: &str, directory: &str) - -> DIFile { + -> &'ll DIFile { let key = (Symbol::intern(file_name), Symbol::intern(directory)); if let Some(file_metadata) = debug_context(cx).created_files.borrow().get(&key) { @@ -731,9 +758,7 @@ fn file_metadata_raw(cx: &CodegenCx, file_metadata } -fn basic_type_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, - t: Ty<'tcx>) -> DIType { - +fn basic_type_metadata(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll DIType { debug!("basic_type_metadata: {:?}", t); let (name, encoding) = match t.sty { @@ -768,19 +793,22 @@ fn basic_type_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, return ty_metadata; } -fn foreign_type_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, - t: Ty<'tcx>, - unique_type_id: UniqueTypeId) -> DIType { +fn foreign_type_metadata( + cx: &CodegenCx<'ll, 'tcx>, + t: Ty<'tcx>, + unique_type_id: UniqueTypeId, +) -> &'ll DIType { debug!("foreign_type_metadata: {:?}", t); let name = compute_debuginfo_type_name(cx, t, false); create_struct_stub(cx, t, &name, unique_type_id, NO_SCOPE_METADATA) } -fn pointer_type_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, - pointer_type: Ty<'tcx>, - pointee_type_metadata: DIType) - -> DIType { +fn pointer_type_metadata( + cx: &CodegenCx<'ll, 'tcx>, + pointer_type: Ty<'tcx>, + pointee_type_metadata: &'ll DIType, +) -> &'ll DIType { let (pointer_size, pointer_align) = cx.size_and_align_of(pointer_type); let name = compute_debuginfo_type_name(cx, pointer_type, false); let name = CString::new(name).unwrap(); @@ -796,8 +824,8 @@ fn pointer_type_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, pub fn compile_unit_metadata(tcx: TyCtxt, codegen_unit_name: &str, - debug_context: &CrateDebugContext) - -> DIDescriptor { + debug_context: &CrateDebugContext<'ll, '_>) + -> &'ll DIDescriptor { let mut name_in_debuginfo = match tcx.sess.local_crate_source_file { Some(ref path) => path.clone(), None => PathBuf::from(&*tcx.crate_name(LOCAL_CRATE).as_str()), @@ -872,13 +900,13 @@ pub fn compile_unit_metadata(tcx: TyCtxt, } } -struct MetadataCreationResult { - metadata: DIType, +struct MetadataCreationResult<'ll> { + metadata: &'ll DIType, already_stored_in_typemap: bool } -impl MetadataCreationResult { - fn new(metadata: DIType, already_stored_in_typemap: bool) -> MetadataCreationResult { +impl MetadataCreationResult<'ll> { + fn new(metadata: &'ll DIType, already_stored_in_typemap: bool) -> Self { MetadataCreationResult { metadata, already_stored_in_typemap, @@ -889,9 +917,9 @@ impl MetadataCreationResult { // Description of a type member, which can either be a regular field (as in // structs or tuples) or an enum variant. #[derive(Debug)] -struct MemberDescription { +struct MemberDescription<'ll> { name: String, - type_metadata: DIType, + type_metadata: &'ll DIType, offset: Size, size: Size, align: Align, @@ -902,17 +930,17 @@ struct MemberDescription { // for some record-like type. MemberDescriptionFactories are used to defer the // creation of type member descriptions in order to break cycles arising from // recursive type definitions. -enum MemberDescriptionFactory<'tcx> { +enum MemberDescriptionFactory<'ll, 'tcx> { StructMDF(StructMemberDescriptionFactory<'tcx>), TupleMDF(TupleMemberDescriptionFactory<'tcx>), - EnumMDF(EnumMemberDescriptionFactory<'tcx>), + EnumMDF(EnumMemberDescriptionFactory<'ll, 'tcx>), UnionMDF(UnionMemberDescriptionFactory<'tcx>), - VariantMDF(VariantMemberDescriptionFactory<'tcx>) + VariantMDF(VariantMemberDescriptionFactory<'ll, 'tcx>) } -impl<'tcx> MemberDescriptionFactory<'tcx> { - fn create_member_descriptions<'a>(&self, cx: &CodegenCx<'a, 'tcx>) - -> Vec { +impl MemberDescriptionFactory<'ll, 'tcx> { + fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>) + -> Vec> { match *self { StructMDF(ref this) => { this.create_member_descriptions(cx) @@ -945,8 +973,8 @@ struct StructMemberDescriptionFactory<'tcx> { } impl<'tcx> StructMemberDescriptionFactory<'tcx> { - fn create_member_descriptions<'a>(&self, cx: &CodegenCx<'a, 'tcx>) - -> Vec { + fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>) + -> Vec> { let layout = cx.layout_of(self.ty); self.variant.fields.iter().enumerate().map(|(i, f)| { let name = if self.variant.ctor_kind == CtorKind::Fn { @@ -969,11 +997,12 @@ impl<'tcx> StructMemberDescriptionFactory<'tcx> { } -fn prepare_struct_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, - struct_type: Ty<'tcx>, - unique_type_id: UniqueTypeId, - span: Span) - -> RecursiveTypeDescription<'tcx> { +fn prepare_struct_metadata( + cx: &CodegenCx<'ll, 'tcx>, + struct_type: Ty<'tcx>, + unique_type_id: UniqueTypeId, + span: Span, +) -> RecursiveTypeDescription<'ll, 'tcx> { let struct_name = compute_debuginfo_type_name(cx, struct_type, false); let (struct_def_id, variant) = match struct_type.sty { @@ -987,7 +1016,7 @@ fn prepare_struct_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, struct_type, &struct_name, unique_type_id, - NonNull::new(containing_scope)); + Some(containing_scope)); create_and_register_recursive_type_forward_declaration( cx, @@ -1014,8 +1043,8 @@ struct TupleMemberDescriptionFactory<'tcx> { } impl<'tcx> TupleMemberDescriptionFactory<'tcx> { - fn create_member_descriptions<'a>(&self, cx: &CodegenCx<'a, 'tcx>) - -> Vec { + fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>) + -> Vec> { let layout = cx.layout_of(self.ty); self.component_types.iter().enumerate().map(|(i, &component_type)| { let (size, align) = cx.size_and_align_of(component_type); @@ -1031,12 +1060,13 @@ impl<'tcx> TupleMemberDescriptionFactory<'tcx> { } } -fn prepare_tuple_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, - tuple_type: Ty<'tcx>, - component_types: &[Ty<'tcx>], - unique_type_id: UniqueTypeId, - span: Span) - -> RecursiveTypeDescription<'tcx> { +fn prepare_tuple_metadata( + cx: &CodegenCx<'ll, 'tcx>, + tuple_type: Ty<'tcx>, + component_types: &[Ty<'tcx>], + unique_type_id: UniqueTypeId, + span: Span, +) -> RecursiveTypeDescription<'ll, 'tcx> { let tuple_name = compute_debuginfo_type_name(cx, tuple_type, false); create_and_register_recursive_type_forward_declaration( @@ -1067,8 +1097,8 @@ struct UnionMemberDescriptionFactory<'tcx> { } impl<'tcx> UnionMemberDescriptionFactory<'tcx> { - fn create_member_descriptions<'a>(&self, cx: &CodegenCx<'a, 'tcx>) - -> Vec { + fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>) + -> Vec> { self.variant.fields.iter().enumerate().map(|(i, f)| { let field = self.layout.field(cx, i); let (size, align) = field.size_and_align(); @@ -1084,11 +1114,12 @@ impl<'tcx> UnionMemberDescriptionFactory<'tcx> { } } -fn prepare_union_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, - union_type: Ty<'tcx>, - unique_type_id: UniqueTypeId, - span: Span) - -> RecursiveTypeDescription<'tcx> { +fn prepare_union_metadata( + cx: &CodegenCx<'ll, 'tcx>, + union_type: Ty<'tcx>, + unique_type_id: UniqueTypeId, + span: Span, +) -> RecursiveTypeDescription<'ll, 'tcx> { let union_name = compute_debuginfo_type_name(cx, union_type, false); let (union_def_id, variant) = match union_type.sty { @@ -1126,17 +1157,17 @@ fn prepare_union_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, // the members of this union; so for every variant of the given enum, this // factory will produce one MemberDescription (all with no name and a fixed // offset of zero bytes). -struct EnumMemberDescriptionFactory<'tcx> { +struct EnumMemberDescriptionFactory<'ll, 'tcx> { enum_type: Ty<'tcx>, layout: TyLayout<'tcx>, - discriminant_type_metadata: Option, - containing_scope: DIScope, + discriminant_type_metadata: Option<&'ll DIType>, + containing_scope: &'ll DIScope, span: Span, } -impl<'tcx> EnumMemberDescriptionFactory<'tcx> { - fn create_member_descriptions<'a>(&self, cx: &CodegenCx<'a, 'tcx>) - -> Vec { +impl EnumMemberDescriptionFactory<'ll, 'tcx> { + fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>) + -> Vec> { let adt = &self.enum_type.ty_adt_def().unwrap(); match self.layout.variants { layout::Variants::Single { .. } if adt.variants.is_empty() => vec![], @@ -1261,17 +1292,17 @@ impl<'tcx> EnumMemberDescriptionFactory<'tcx> { } // Creates MemberDescriptions for the fields of a single enum variant. -struct VariantMemberDescriptionFactory<'tcx> { +struct VariantMemberDescriptionFactory<'ll, 'tcx> { // Cloned from the layout::Struct describing the variant. offsets: Vec, args: Vec<(String, Ty<'tcx>)>, - discriminant_type_metadata: Option, + discriminant_type_metadata: Option<&'ll DIType>, span: Span, } -impl<'tcx> VariantMemberDescriptionFactory<'tcx> { - fn create_member_descriptions<'a>(&self, cx: &CodegenCx<'a, 'tcx>) - -> Vec { +impl VariantMemberDescriptionFactory<'ll, 'tcx> { + fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>) + -> Vec> { self.args.iter().enumerate().map(|(i, &(ref name, ty))| { let (size, align) = cx.size_and_align_of(ty); MemberDescription { @@ -1290,8 +1321,8 @@ impl<'tcx> VariantMemberDescriptionFactory<'tcx> { } #[derive(Copy, Clone)] -enum EnumDiscriminantInfo { - RegularDiscriminant(DIType), +enum EnumDiscriminantInfo<'ll> { + RegularDiscriminant(&'ll DIType), OptimizedDiscriminant, NoDiscriminant } @@ -1300,13 +1331,14 @@ enum EnumDiscriminantInfo { // of the variant, and (3) a MemberDescriptionFactory for producing the // descriptions of the fields of the variant. This is a rudimentary version of a // full RecursiveTypeDescription. -fn describe_enum_variant<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, - layout: layout::TyLayout<'tcx>, - variant: &'tcx ty::VariantDef, - discriminant_info: EnumDiscriminantInfo, - containing_scope: DIScope, - span: Span) - -> (DICompositeType, MemberDescriptionFactory<'tcx>) { +fn describe_enum_variant( + cx: &CodegenCx<'ll, 'tcx>, + layout: layout::TyLayout<'tcx>, + variant: &'tcx ty::VariantDef, + discriminant_info: EnumDiscriminantInfo<'ll>, + containing_scope: &'ll DIScope, + span: Span, +) -> (&'ll DICompositeType, MemberDescriptionFactory<'ll, 'tcx>) { let variant_name = variant.name.as_str(); let unique_type_id = debug_context(cx).type_map .borrow_mut() @@ -1319,7 +1351,7 @@ fn describe_enum_variant<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, layout.ty, &variant_name, unique_type_id, - NonNull::new(containing_scope)); + Some(containing_scope)); // If this is not a univariant enum, there is also the discriminant field. let (discr_offset, discr_arg) = match discriminant_info { @@ -1360,12 +1392,13 @@ fn describe_enum_variant<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, (metadata_stub, member_description_factory) } -fn prepare_enum_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, - enum_type: Ty<'tcx>, - enum_def_id: DefId, - unique_type_id: UniqueTypeId, - span: Span) - -> RecursiveTypeDescription<'tcx> { +fn prepare_enum_metadata( + cx: &CodegenCx<'ll, 'tcx>, + enum_type: Ty<'tcx>, + enum_def_id: DefId, + unique_type_id: UniqueTypeId, + span: Span, +) -> RecursiveTypeDescription<'ll, 'tcx> { let enum_name = compute_debuginfo_type_name(cx, enum_type, false); let containing_scope = get_namespace_for_item(cx, enum_def_id); @@ -1384,7 +1417,7 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, let token = v.name.as_str(); let name = CString::new(token.as_bytes()).unwrap(); unsafe { - NonNull::new(llvm::LLVMRustDIBuilderCreateEnumerator( + Some(llvm::LLVMRustDIBuilderCreateEnumerator( DIB(cx), name.as_ptr(), // FIXME: what if enumeration has i128 discriminant? @@ -1491,18 +1524,19 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, /// results in a LLVM struct. /// /// Examples of Rust types to use this are: structs, tuples, boxes, vecs, and enums. -fn composite_type_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, - composite_type: Ty<'tcx>, - composite_type_name: &str, - composite_type_unique_id: UniqueTypeId, - member_descriptions: &[MemberDescription], - containing_scope: Option>, - - // Ignore source location information as long as it - // can't be reconstructed for non-local crates. - _file_metadata: DIFile, - _definition_span: Span) - -> DICompositeType { +fn composite_type_metadata( + cx: &CodegenCx<'ll, 'tcx>, + composite_type: Ty<'tcx>, + composite_type_name: &str, + composite_type_unique_id: UniqueTypeId, + member_descriptions: &[MemberDescription<'ll>], + containing_scope: Option<&'ll DIScope>, + + // Ignore source location information as long as it + // can't be reconstructed for non-local crates. + _file_metadata: &'ll DIFile, + _definition_span: Span, +) -> &'ll DICompositeType { // Create the (empty) struct metadata node ... let composite_type_metadata = create_struct_stub(cx, composite_type, @@ -1517,9 +1551,9 @@ fn composite_type_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, return composite_type_metadata; } -fn set_members_of_composite_type(cx: &CodegenCx, - composite_type_metadata: DICompositeType, - member_descriptions: &[MemberDescription]) { +fn set_members_of_composite_type(cx: &CodegenCx<'ll, '_>, + composite_type_metadata: &'ll DICompositeType, + member_descriptions: &[MemberDescription<'ll>]) { // In some rare cases LLVM metadata uniquing would lead to an existing type // description being used instead of a new one created in // create_struct_stub. This would cause a hard to trace assertion in @@ -1543,7 +1577,7 @@ fn set_members_of_composite_type(cx: &CodegenCx, let member_name = member_description.name.as_bytes(); let member_name = CString::new(member_name).unwrap(); unsafe { - NonNull::new(llvm::LLVMRustDIBuilderCreateMemberType( + Some(llvm::LLVMRustDIBuilderCreateMemberType( DIB(cx), composite_type_metadata, member_name.as_ptr(), @@ -1568,12 +1602,13 @@ fn set_members_of_composite_type(cx: &CodegenCx, // A convenience wrapper around LLVMRustDIBuilderCreateStructType(). Does not do // any caching, does not add any fields to the struct. This can be done later // with set_members_of_composite_type(). -fn create_struct_stub<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, - struct_type: Ty<'tcx>, - struct_type_name: &str, - unique_type_id: UniqueTypeId, - containing_scope: Option>) - -> DICompositeType { +fn create_struct_stub( + cx: &CodegenCx<'ll, 'tcx>, + struct_type: Ty<'tcx>, + struct_type_name: &str, + unique_type_id: UniqueTypeId, + containing_scope: Option<&'ll DIScope>, +) -> &'ll DICompositeType { let (struct_size, struct_align) = cx.size_and_align_of(struct_type); let name = CString::new(struct_type_name).unwrap(); @@ -1605,12 +1640,13 @@ fn create_struct_stub<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, return metadata_stub; } -fn create_union_stub<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, - union_type: Ty<'tcx>, - union_type_name: &str, - unique_type_id: UniqueTypeId, - containing_scope: DIScope) - -> DICompositeType { +fn create_union_stub( + cx: &CodegenCx<'ll, 'tcx>, + union_type: Ty<'tcx>, + union_type_name: &str, + unique_type_id: UniqueTypeId, + containing_scope: &'ll DIScope, +) -> &'ll DICompositeType { let (union_size, union_align) = cx.size_and_align_of(union_type); let name = CString::new(union_type_name).unwrap(); @@ -1632,7 +1668,7 @@ fn create_union_stub<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, union_size.bits(), union_align.abi_bits() as u32, DIFlags::FlagZero, - NonNull::new(empty_array), + Some(empty_array), 0, // RuntimeLang unique_type_id.as_ptr()) }; @@ -1686,7 +1722,7 @@ pub fn create_global_var_metadata(cx: &CodegenCx, unsafe { llvm::LLVMRustDIBuilderCreateStaticVariable(DIB(cx), - NonNull::new(var_scope), + Some(var_scope), var_name.as_ptr(), // If null, linkage_name field is omitted, // which is what we want for no_mangle statics @@ -1704,11 +1740,12 @@ pub fn create_global_var_metadata(cx: &CodegenCx, } // Creates an "extension" of an existing DIScope into another file. -pub fn extend_scope_to_file(cx: &CodegenCx, - scope_metadata: DIScope, - file: &syntax_pos::FileMap, - defining_crate: CrateNum) - -> DILexicalBlock { +pub fn extend_scope_to_file( + cx: &CodegenCx<'ll, '_>, + scope_metadata: &'ll DIScope, + file: &syntax_pos::FileMap, + defining_crate: CrateNum, +) -> &'ll DILexicalBlock { let file_metadata = file_metadata(cx, &file.name, defining_crate); unsafe { llvm::LLVMRustDIBuilderCreateLexicalBlockFile( @@ -1754,7 +1791,7 @@ pub fn create_vtable_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, None, empty_array, 0, - NonNull::new(type_metadata), + Some(type_metadata), name.as_ptr() ); diff --git a/src/librustc_codegen_llvm/debuginfo/mod.rs b/src/librustc_codegen_llvm/debuginfo/mod.rs index 43534b8ec2e03..27a4c60b36df3 100644 --- a/src/librustc_codegen_llvm/debuginfo/mod.rs +++ b/src/librustc_codegen_llvm/debuginfo/mod.rs @@ -39,7 +39,6 @@ use rustc::util::nodemap::{DefIdMap, FxHashMap, FxHashSet}; use libc::c_uint; use std::cell::{Cell, RefCell}; use std::ffi::CString; -use std::ptr::NonNull; use syntax_pos::{self, Span, Pos}; use syntax::ast; @@ -71,15 +70,15 @@ pub struct CrateDebugContext<'a, 'tcx> { llcontext: &'a llvm::Context, llmod: &'a llvm::Module, builder: &'a DIBuilder, - created_files: RefCell>, - created_enum_disr_types: RefCell>, + created_files: RefCell>, + created_enum_disr_types: RefCell>, - type_map: RefCell>, - namespace_map: RefCell>, + type_map: RefCell>, + namespace_map: RefCell>, // This collection is used to assert that composite types (structs, enums, // ...) have their members only set once: - composite_types_completed: RefCell>, + composite_types_completed: RefCell>, } impl<'a, 'tcx> CrateDebugContext<'a, 'tcx> { @@ -101,14 +100,14 @@ impl<'a, 'tcx> CrateDebugContext<'a, 'tcx> { } } -pub enum FunctionDebugContext { - RegularContext(FunctionDebugContextData), +pub enum FunctionDebugContext<'ll> { + RegularContext(FunctionDebugContextData<'ll>), DebugInfoDisabled, FunctionWithoutDebugInfo, } -impl FunctionDebugContext { - pub fn get_ref<'a>(&'a self, span: Span) -> &'a FunctionDebugContextData { +impl FunctionDebugContext<'ll> { + pub fn get_ref<'a>(&'a self, span: Span) -> &'a FunctionDebugContextData<'ll> { match *self { FunctionDebugContext::RegularContext(ref data) => data, FunctionDebugContext::DebugInfoDisabled => { @@ -130,8 +129,8 @@ impl FunctionDebugContext { } } -pub struct FunctionDebugContextData { - fn_metadata: DISubprogram, +pub struct FunctionDebugContextData<'ll> { + fn_metadata: &'ll DISubprogram, source_locations_enabled: Cell, pub defining_crate: CrateNum, } @@ -201,11 +200,13 @@ pub fn finalize(cx: &CodegenCx) { /// for debug info creation. The function may also return another variant of the /// FunctionDebugContext enum which indicates why no debuginfo should be created /// for the function. -pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, - instance: Instance<'tcx>, - sig: ty::FnSig<'tcx>, - llfn: ValueRef, - mir: &mir::Mir) -> FunctionDebugContext { +pub fn create_function_debug_context( + cx: &CodegenCx<'ll, 'tcx>, + instance: Instance<'tcx>, + sig: ty::FnSig<'tcx>, + llfn: ValueRef, + mir: &mir::Mir, +) -> FunctionDebugContext<'ll> { if cx.sess().opts.debuginfo == NoDebugInfo { return FunctionDebugContext::DebugInfoDisabled; } @@ -302,8 +303,10 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, return FunctionDebugContext::RegularContext(fn_debug_context); - fn get_function_signature<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, - sig: ty::FnSig<'tcx>) -> DIArray { + fn get_function_signature( + cx: &CodegenCx<'ll, 'tcx>, + sig: ty::FnSig<'tcx>, + ) -> &'ll DIArray { if cx.sess().opts.debuginfo == LimitedDebugInfo { return create_DIArray(DIB(cx), &[]); } @@ -313,7 +316,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, // Return type -- llvm::DIBuilder wants this at index 0 signature.push(match sig.output().sty { ty::TyTuple(ref tys) if tys.is_empty() => None, - _ => NonNull::new(type_metadata(cx, sig.output(), syntax_pos::DUMMY_SP)) + _ => Some(type_metadata(cx, sig.output(), syntax_pos::DUMMY_SP)) }); let inputs = if sig.abi == Abi::RustCall { @@ -342,11 +345,11 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, } _ => t }; - NonNull::new(type_metadata(cx, t, syntax_pos::DUMMY_SP)) + Some(type_metadata(cx, t, syntax_pos::DUMMY_SP)) })); } else { signature.extend(inputs.iter().map(|t| { - NonNull::new(type_metadata(cx, t, syntax_pos::DUMMY_SP)) + Some(type_metadata(cx, t, syntax_pos::DUMMY_SP)) })); } @@ -354,7 +357,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, if let ty::TyTuple(args) = sig.inputs()[sig.inputs().len() - 1].sty { signature.extend( args.iter().map(|argument_type| { - NonNull::new(type_metadata(cx, argument_type, syntax_pos::DUMMY_SP)) + Some(type_metadata(cx, argument_type, syntax_pos::DUMMY_SP)) }) ); } @@ -363,13 +366,13 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, return create_DIArray(DIB(cx), &signature[..]); } - fn get_template_parameters<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, - generics: &ty::Generics, - substs: &Substs<'tcx>, - file_metadata: DIFile, - name_to_append_suffix_to: &mut String) - -> DIArray - { + fn get_template_parameters( + cx: &CodegenCx<'ll, 'tcx>, + generics: &ty::Generics, + substs: &Substs<'tcx>, + file_metadata: &'ll DIFile, + name_to_append_suffix_to: &mut String, + ) -> &'ll DIArray { if substs.types().next().is_none() { return create_DIArray(DIB(cx), &[]); } @@ -399,14 +402,15 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, type_metadata(cx, actual_type, syntax_pos::DUMMY_SP); let name = CString::new(name.as_str().as_bytes()).unwrap(); Some(unsafe { - NonNull::new(llvm::LLVMRustDIBuilderCreateTemplateTypeParameter( + Some(llvm::LLVMRustDIBuilderCreateTemplateTypeParameter( DIB(cx), None, name.as_ptr(), actual_type_metadata, file_metadata, 0, - 0)) + 0, + )) }) } else { None @@ -429,9 +433,10 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, names } - fn get_containing_scope<'cx, 'tcx>(cx: &CodegenCx<'cx, 'tcx>, - instance: Instance<'tcx>) - -> DIScope { + fn get_containing_scope( + cx: &CodegenCx<'ll, 'tcx>, + instance: Instance<'tcx>, + ) -> &'ll DIScope { // First, let's see if this is a method within an inherent impl. Because // if yes, we want to make the result subroutine DIE a child of the // subroutine's self-type. @@ -473,10 +478,10 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, pub fn declare_local( bx: &Builder<'a, 'll, 'tcx>, - dbg_context: &FunctionDebugContext, + dbg_context: &FunctionDebugContext<'ll>, variable_name: ast::Name, variable_type: Ty<'tcx>, - scope_metadata: DIScope, + scope_metadata: &'ll DIScope, variable_access: VariableAccess, variable_kind: VariableKind, span: Span, diff --git a/src/librustc_codegen_llvm/debuginfo/namespace.rs b/src/librustc_codegen_llvm/debuginfo/namespace.rs index b651f813408a0..9f1141a7e7db0 100644 --- a/src/librustc_codegen_llvm/debuginfo/namespace.rs +++ b/src/librustc_codegen_llvm/debuginfo/namespace.rs @@ -22,7 +22,6 @@ use rustc::hir::map::DefPathData; use common::CodegenCx; use std::ffi::CString; -use std::ptr::NonNull; pub fn mangled_name_of_instance<'a, 'tcx>( cx: &CodegenCx<'a, 'tcx>, @@ -32,17 +31,17 @@ pub fn mangled_name_of_instance<'a, 'tcx>( tcx.symbol_name(instance) } -pub fn item_namespace(cx: &CodegenCx, def_id: DefId) -> DIScope { +pub fn item_namespace(cx: &CodegenCx<'ll, '_>, def_id: DefId) -> &'ll DIScope { if let Some(&scope) = debug_context(cx).namespace_map.borrow().get(&def_id) { return scope; } let def_key = cx.tcx.def_key(def_id); - let parent_scope = def_key.parent.and_then(|parent| { - NonNull::new(item_namespace(cx, DefId { + let parent_scope = def_key.parent.map(|parent| { + item_namespace(cx, DefId { krate: def_id.krate, index: parent - })) + }) }); let namespace_name = match def_key.disambiguated_data.data { diff --git a/src/librustc_codegen_llvm/debuginfo/source_loc.rs b/src/librustc_codegen_llvm/debuginfo/source_loc.rs index 1a1462da3dd9c..ae117ffd3ecd1 100644 --- a/src/librustc_codegen_llvm/debuginfo/source_loc.rs +++ b/src/librustc_codegen_llvm/debuginfo/source_loc.rs @@ -15,7 +15,7 @@ use super::metadata::UNKNOWN_COLUMN_NUMBER; use super::FunctionDebugContext; use llvm; -use llvm::debuginfo::{DIScope_opaque, DIScope}; +use llvm::debuginfo::DIScope; use builder::Builder; use libc::c_uint; @@ -26,7 +26,10 @@ use syntax_pos::{Span, Pos}; /// /// Maps to a call to llvm::LLVMSetCurrentDebugLocation(...). pub fn set_source_location( - debug_context: &FunctionDebugContext, bx: &Builder, scope: Option>, span: Span + debug_context: &FunctionDebugContext<'ll>, + bx: &Builder<'_, 'll, '_>, + scope: Option<&'ll DIScope>, + span: Span, ) { let function_debug_context = match *debug_context { FunctionDebugContext::DebugInfoDisabled => return, @@ -40,7 +43,7 @@ pub fn set_source_location( let dbg_loc = if function_debug_context.source_locations_enabled.get() { debug!("set_source_location: {}", bx.sess().codemap().span_to_string(span)); let loc = span_start(bx.cx, span); - InternalDebugLocation::new(scope.unwrap().as_ptr(), loc.line, loc.col.to_usize()) + InternalDebugLocation::new(scope.unwrap(), loc.line, loc.col.to_usize()) } else { UnknownLocation }; @@ -53,7 +56,7 @@ pub fn set_source_location( /// they are disabled when beginning to codegen a new function. This functions /// switches source location emitting on and must therefore be called before the /// first real statement/expression of the function is codegened. -pub fn start_emitting_source_locations(dbg_context: &FunctionDebugContext) { +pub fn start_emitting_source_locations(dbg_context: &FunctionDebugContext<'ll>) { match *dbg_context { FunctionDebugContext::RegularContext(ref data) => { data.source_locations_enabled.set(true) @@ -64,13 +67,13 @@ pub fn start_emitting_source_locations(dbg_context: &FunctionDebugContext) { #[derive(Copy, Clone, PartialEq)] -pub enum InternalDebugLocation { - KnownLocation { scope: DIScope, line: usize, col: usize }, +pub enum InternalDebugLocation<'ll> { + KnownLocation { scope: &'ll DIScope, line: usize, col: usize }, UnknownLocation } -impl InternalDebugLocation { - pub fn new(scope: DIScope, line: usize, col: usize) -> InternalDebugLocation { +impl InternalDebugLocation<'ll> { + pub fn new(scope: &'ll DIScope, line: usize, col: usize) -> Self { KnownLocation { scope, line, @@ -79,7 +82,7 @@ impl InternalDebugLocation { } } -pub fn set_debug_location(bx: &Builder, debug_location: InternalDebugLocation) { +pub fn set_debug_location(bx: &Builder<'_, 'll, '_>, debug_location: InternalDebugLocation<'ll>) { let metadata_node = match debug_location { KnownLocation { scope, line, col } => { // For MSVC, set the column number to zero. diff --git a/src/librustc_codegen_llvm/debuginfo/utils.rs b/src/librustc_codegen_llvm/debuginfo/utils.rs index 602a64ae3b33a..d4d817abd5600 100644 --- a/src/librustc_codegen_llvm/debuginfo/utils.rs +++ b/src/librustc_codegen_llvm/debuginfo/utils.rs @@ -17,10 +17,9 @@ use rustc::hir::def_id::DefId; use rustc::ty::DefIdTree; use llvm; -use llvm::debuginfo::{DIScope, DIBuilder, DIDescriptor_opaque, DIArray}; +use llvm::debuginfo::{DIScope, DIBuilder, DIDescriptor, DIArray}; use common::{CodegenCx}; -use std::ptr::NonNull; use syntax_pos::{self, Span}; pub fn is_node_local_to_unit(cx: &CodegenCx, def_id: DefId) -> bool @@ -37,7 +36,7 @@ pub fn is_node_local_to_unit(cx: &CodegenCx, def_id: DefId) -> bool } #[allow(non_snake_case)] -pub fn create_DIArray(builder: &DIBuilder, arr: &[Option>]) -> DIArray { +pub fn create_DIArray(builder: &'ll DIBuilder, arr: &[Option<&'ll DIDescriptor>]) -> &'ll DIArray { return unsafe { llvm::LLVMRustDIBuilderGetOrCreateArray(builder, arr.as_ptr(), arr.len() as u32) }; @@ -49,7 +48,7 @@ pub fn span_start(cx: &CodegenCx, span: Span) -> syntax_pos::Loc { } #[inline] -pub fn debug_context(cx: &'a CodegenCx<'ll, 'tcx>) -> &'a CrateDebugContext<'a, 'tcx> { +pub fn debug_context(cx: &'a CodegenCx<'ll, 'tcx>) -> &'a CrateDebugContext<'ll, 'tcx> { cx.dbg_cx.as_ref().unwrap() } @@ -59,7 +58,7 @@ pub fn DIB(cx: &CodegenCx<'ll, '_>) -> &'ll DIBuilder { cx.dbg_cx.as_ref().unwrap().builder } -pub fn get_namespace_for_item(cx: &CodegenCx, def_id: DefId) -> DIScope { +pub fn get_namespace_for_item(cx: &CodegenCx<'ll, '_>, def_id: DefId) -> &'ll DIScope { item_namespace(cx, cx.tcx.parent(def_id) .expect("get_namespace_for_item: missing parent?")) } diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index 7dca1e907a857..e52ebc7f34bea 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -12,7 +12,7 @@ use intrinsics::{self, Intrinsic}; use llvm; -use llvm::{ValueRef}; +use llvm::{TypeKind, ValueRef}; use abi::{Abi, FnType, LlvmType, PassMode}; use mir::place::PlaceRef; use mir::operand::{OperandRef, OperandValue}; @@ -1060,7 +1060,7 @@ fn generic_simd_intrinsic( found `{}` with length {}", in_len, in_ty, ret_ty, out_len); - require!(llret_ty.element_type().kind() == llvm::Integer, + require!(llret_ty.element_type().kind() == TypeKind::Integer, "expected return type with integer elements, found `{}` with non-integer `{}`", ret_ty, ret_ty.simd_type(tcx)); diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index b202a1bf2f70e..389cfa1d7b107 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -15,9 +15,9 @@ // https://reviews.llvm.org/D26769 use super::debuginfo::{ - DIBuilder, DIDescriptor_opaque, DIDescriptor, DIFile, DILexicalBlock, DISubprogram, DIType_opaque, - DIType, DIBasicType, DIDerivedType, DICompositeType, DIScope_opaque, DIScope, DIVariable, - DIGlobalVariable, DIArray_opaque, DIArray, DISubrange, DITemplateTypeParameter, DIEnumerator, + DIBuilder, DIDescriptor, DIFile, DILexicalBlock, DISubprogram, DIType, + DIBasicType, DIDerivedType, DICompositeType, DIScope, DIVariable, + DIGlobalVariable, DIArray, DISubrange, DITemplateTypeParameter, DIEnumerator, DINameSpace, DIFlags, }; @@ -380,8 +380,7 @@ extern { pub type Context; } extern { pub type Type; } extern { pub type Value_opaque; } pub type ValueRef = *mut Value_opaque; -extern { pub type Metadata_opaque; } -pub type MetadataRef = *mut Metadata_opaque; +extern { pub type Metadata; } extern { pub type BasicBlock_opaque; } pub type BasicBlockRef = *mut BasicBlock_opaque; extern { pub type Builder; } @@ -431,28 +430,23 @@ pub type InlineAsmDiagHandler = unsafe extern "C" fn(SMDiagnosticRef, *const c_v pub mod debuginfo { - use super::Metadata_opaque; + use super::Metadata; extern { pub type DIBuilder; } - pub type DIDescriptor_opaque = Metadata_opaque; - pub type DIDescriptor = *mut DIDescriptor_opaque; - pub type DIScope_opaque = DIDescriptor_opaque; - pub type DIScope = *mut DIScope_opaque; - pub type DILocation = DIDescriptor; + pub type DIDescriptor = Metadata; + pub type DIScope = DIDescriptor; pub type DIFile = DIScope; pub type DILexicalBlock = DIScope; pub type DISubprogram = DIScope; pub type DINameSpace = DIScope; - pub type DIType_opaque = DIDescriptor_opaque; - pub type DIType = *mut DIType_opaque; + 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_opaque = DIDescriptor_opaque; - pub type DIArray = *mut DIArray_opaque; + pub type DIArray = DIDescriptor; pub type DISubrange = DIDescriptor; pub type DIEnumerator = DIDescriptor; pub type DITemplateTypeParameter = DIDescriptor; @@ -1366,7 +1360,7 @@ extern "C" { pub fn LLVMRustAddModuleFlag(M: &Module, name: *const c_char, value: u32); - pub fn LLVMRustMetadataAsValue(C: &Context, MD: MetadataRef) -> ValueRef; + pub fn LLVMRustMetadataAsValue(C: &'a Context, MD: &'a Metadata) -> ValueRef; pub fn LLVMRustDIBuilderCreate(M: &Module) -> &DIBuilder; @@ -1374,149 +1368,149 @@ extern "C" { pub fn LLVMRustDIBuilderFinalize(Builder: &DIBuilder); - pub fn LLVMRustDIBuilderCreateCompileUnit(Builder: &DIBuilder, + pub fn LLVMRustDIBuilderCreateCompileUnit(Builder: &'a DIBuilder, Lang: c_uint, - File: DIFile, + File: &'a DIFile, Producer: *const c_char, isOptimized: bool, Flags: *const c_char, RuntimeVer: c_uint, SplitName: *const c_char) - -> DIDescriptor; + -> &'a DIDescriptor; pub fn LLVMRustDIBuilderCreateFile(Builder: &DIBuilder, Filename: *const c_char, Directory: *const c_char) - -> DIFile; + -> &DIFile; - pub fn LLVMRustDIBuilderCreateSubroutineType(Builder: &DIBuilder, - File: DIFile, - ParameterTypes: DIArray) - -> DICompositeType; + pub fn LLVMRustDIBuilderCreateSubroutineType(Builder: &'a DIBuilder, + File: &'a DIFile, + ParameterTypes: &'a DIArray) + -> &'a DICompositeType; - pub fn LLVMRustDIBuilderCreateFunction(Builder: &DIBuilder, - Scope: DIDescriptor, + pub fn LLVMRustDIBuilderCreateFunction(Builder: &'a DIBuilder, + Scope: &'a DIDescriptor, Name: *const c_char, LinkageName: *const c_char, - File: DIFile, + File: &'a DIFile, LineNo: c_uint, - Ty: DIType, + Ty: &'a DIType, isLocalToUnit: bool, isDefinition: bool, ScopeLine: c_uint, Flags: DIFlags, isOptimized: bool, Fn: ValueRef, - TParam: DIArray, - Decl: Option>) - -> DISubprogram; + TParam: &'a DIArray, + Decl: Option<&'a DIDescriptor>) + -> &'a DISubprogram; pub fn LLVMRustDIBuilderCreateBasicType(Builder: &DIBuilder, Name: *const c_char, SizeInBits: u64, AlignInBits: u32, Encoding: c_uint) - -> DIBasicType; + -> &DIBasicType; - pub fn LLVMRustDIBuilderCreatePointerType(Builder: &DIBuilder, - PointeeTy: DIType, + pub fn LLVMRustDIBuilderCreatePointerType(Builder: &'a DIBuilder, + PointeeTy: &'a DIType, SizeInBits: u64, AlignInBits: u32, Name: *const c_char) - -> DIDerivedType; + -> &'a DIDerivedType; - pub fn LLVMRustDIBuilderCreateStructType(Builder: &DIBuilder, - Scope: Option>, + pub fn LLVMRustDIBuilderCreateStructType(Builder: &'a DIBuilder, + Scope: Option<&'a DIDescriptor>, Name: *const c_char, - File: DIFile, + File: &'a DIFile, LineNumber: c_uint, SizeInBits: u64, AlignInBits: u32, Flags: DIFlags, - DerivedFrom: Option>, - Elements: DIArray, + DerivedFrom: Option<&'a DIType>, + Elements: &'a DIArray, RunTimeLang: c_uint, - VTableHolder: Option>, + VTableHolder: Option<&'a DIType>, UniqueId: *const c_char) - -> DICompositeType; + -> &'a DICompositeType; - pub fn LLVMRustDIBuilderCreateMemberType(Builder: &DIBuilder, - Scope: DIDescriptor, + pub fn LLVMRustDIBuilderCreateMemberType(Builder: &'a DIBuilder, + Scope: &'a DIDescriptor, Name: *const c_char, - File: DIFile, + File: &'a DIFile, LineNo: c_uint, SizeInBits: u64, AlignInBits: u32, OffsetInBits: u64, Flags: DIFlags, - Ty: DIType) - -> DIDerivedType; + Ty: &'a DIType) + -> &'a DIDerivedType; - pub fn LLVMRustDIBuilderCreateLexicalBlock(Builder: &DIBuilder, - Scope: DIScope, - File: DIFile, + pub fn LLVMRustDIBuilderCreateLexicalBlock(Builder: &'a DIBuilder, + Scope: &'a DIScope, + File: &'a DIFile, Line: c_uint, Col: c_uint) - -> DILexicalBlock; + -> &'a DILexicalBlock; - pub fn LLVMRustDIBuilderCreateLexicalBlockFile(Builder: &DIBuilder, - Scope: DIScope, - File: DIFile) - -> DILexicalBlock; + pub fn LLVMRustDIBuilderCreateLexicalBlockFile(Builder: &'a DIBuilder, + Scope: &'a DIScope, + File: &'a DIFile) + -> &'a DILexicalBlock; - pub fn LLVMRustDIBuilderCreateStaticVariable(Builder: &DIBuilder, - Context: Option>, + pub fn LLVMRustDIBuilderCreateStaticVariable(Builder: &'a DIBuilder, + Context: Option<&'a DIScope>, Name: *const c_char, LinkageName: *const c_char, - File: DIFile, + File: &'a DIFile, LineNo: c_uint, - Ty: DIType, + Ty: &'a DIType, isLocalToUnit: bool, Val: ValueRef, - Decl: Option>, + Decl: Option<&'a DIDescriptor>, AlignInBits: u32) - -> DIGlobalVariable; + -> &'a DIGlobalVariable; - pub fn LLVMRustDIBuilderCreateVariable(Builder: &DIBuilder, + pub fn LLVMRustDIBuilderCreateVariable(Builder: &'a DIBuilder, Tag: c_uint, - Scope: DIDescriptor, + Scope: &'a DIDescriptor, Name: *const c_char, - File: DIFile, + File: &'a DIFile, LineNo: c_uint, - Ty: DIType, + Ty: &'a DIType, AlwaysPreserve: bool, Flags: DIFlags, ArgNo: c_uint, AlignInBits: u32) - -> DIVariable; + -> &'a DIVariable; - pub fn LLVMRustDIBuilderCreateArrayType(Builder: &DIBuilder, + pub fn LLVMRustDIBuilderCreateArrayType(Builder: &'a DIBuilder, Size: u64, AlignInBits: u32, - Ty: DIType, - Subscripts: DIArray) - -> DIType; + Ty: &'a DIType, + Subscripts: &'a DIArray) + -> &'a DIType; - pub fn LLVMRustDIBuilderCreateVectorType(Builder: &DIBuilder, + pub fn LLVMRustDIBuilderCreateVectorType(Builder: &'a DIBuilder, Size: u64, AlignInBits: u32, - Ty: DIType, - Subscripts: DIArray) - -> DIType; + Ty: &'a DIType, + Subscripts: &'a DIArray) + -> &'a DIType; pub fn LLVMRustDIBuilderGetOrCreateSubrange(Builder: &DIBuilder, Lo: i64, Count: i64) - -> DISubrange; + -> &DISubrange; - pub fn LLVMRustDIBuilderGetOrCreateArray(Builder: &DIBuilder, - Ptr: *const Option>, + pub fn LLVMRustDIBuilderGetOrCreateArray(Builder: &'a DIBuilder, + Ptr: *const Option<&'a DIDescriptor>, Count: c_uint) - -> DIArray; + -> &'a DIArray; - pub fn LLVMRustDIBuilderInsertDeclareAtEnd(Builder: &DIBuilder, + pub fn LLVMRustDIBuilderInsertDeclareAtEnd(Builder: &'a DIBuilder, Val: ValueRef, - VarInfo: DIVariable, + VarInfo: &'a DIVariable, AddrOps: *const i64, AddrOpsCount: c_uint, DL: ValueRef, @@ -1526,60 +1520,61 @@ extern "C" { pub fn LLVMRustDIBuilderCreateEnumerator(Builder: &DIBuilder, Name: *const c_char, Val: u64) - -> DIEnumerator; + -> &DIEnumerator; - pub fn LLVMRustDIBuilderCreateEnumerationType(Builder: &DIBuilder, - Scope: DIScope, + pub fn LLVMRustDIBuilderCreateEnumerationType(Builder: &'a DIBuilder, + Scope: &'a DIScope, Name: *const c_char, - File: DIFile, + File: &'a DIFile, LineNumber: c_uint, SizeInBits: u64, AlignInBits: u32, - Elements: DIArray, - ClassType: DIType) - -> DIType; + Elements: &'a DIArray, + ClassType: &'a DIType) + -> &'a DIType; - pub fn LLVMRustDIBuilderCreateUnionType(Builder: &DIBuilder, - Scope: DIScope, + pub fn LLVMRustDIBuilderCreateUnionType(Builder: &'a DIBuilder, + Scope: &'a DIScope, Name: *const c_char, - File: DIFile, + File: &'a DIFile, LineNumber: c_uint, SizeInBits: u64, AlignInBits: u32, Flags: DIFlags, - Elements: Option>, + Elements: Option<&'a DIArray>, RunTimeLang: c_uint, UniqueId: *const c_char) - -> DIType; + -> &'a DIType; pub fn LLVMSetUnnamedAddr(GlobalVar: ValueRef, UnnamedAddr: Bool); - pub fn LLVMRustDIBuilderCreateTemplateTypeParameter(Builder: &DIBuilder, - Scope: Option>, + pub fn LLVMRustDIBuilderCreateTemplateTypeParameter(Builder: &'a DIBuilder, + Scope: Option<&'a DIScope>, Name: *const c_char, - Ty: DIType, - File: DIFile, + Ty: &'a DIType, + File: &'a DIFile, LineNo: c_uint, ColumnNo: c_uint) - -> DITemplateTypeParameter; + -> &'a DITemplateTypeParameter; - pub fn LLVMRustDIBuilderCreateNameSpace(Builder: &DIBuilder, - Scope: Option>, + pub fn LLVMRustDIBuilderCreateNameSpace(Builder: &'a DIBuilder, + Scope: Option<&'a DIScope>, Name: *const c_char, - File: DIFile, + File: &'a DIFile, LineNo: c_uint) - -> DINameSpace; - pub fn LLVMRustDICompositeTypeSetTypeArray(Builder: &DIBuilder, - CompositeType: DIType, - TypeArray: DIArray); + -> &'a DINameSpace; + pub fn LLVMRustDICompositeTypeSetTypeArray(Builder: &'a DIBuilder, + CompositeType: &'a DIType, + TypeArray: &'a DIArray); - pub fn LLVMRustDIBuilderCreateDebugLocation(Context: &Context, + + pub fn LLVMRustDIBuilderCreateDebugLocation(Context: &'a Context, Line: c_uint, Column: c_uint, - Scope: DIScope, - InlinedAt: Option>) + Scope: &'a DIScope, + InlinedAt: Option<&'a Metadata>) -> ValueRef; pub fn LLVMRustDIBuilderCreateOpDeref() -> i64; pub fn LLVMRustDIBuilderCreateOpPlusUconst() -> i64; diff --git a/src/librustc_codegen_llvm/llvm/mod.rs b/src/librustc_codegen_llvm/llvm/mod.rs index 75f13e8885866..37f1bf5c1e70f 100644 --- a/src/librustc_codegen_llvm/llvm/mod.rs +++ b/src/librustc_codegen_llvm/llvm/mod.rs @@ -16,7 +16,6 @@ pub use self::IntPredicate::*; pub use self::RealPredicate::*; -pub use self::TypeKind::*; pub use self::AtomicRmwBinOp::*; pub use self::MetadataType::*; pub use self::CodeGenOptSize::*; diff --git a/src/librustc_codegen_llvm/mir/mod.rs b/src/librustc_codegen_llvm/mir/mod.rs index 4b33459740c55..62369ea5792bf 100644 --- a/src/librustc_codegen_llvm/mir/mod.rs +++ b/src/librustc_codegen_llvm/mir/mod.rs @@ -11,7 +11,7 @@ use common::{C_i32, C_null}; use libc::c_uint; use llvm::{self, ValueRef, BasicBlockRef}; -use llvm::debuginfo::DIScope_opaque; +use llvm::debuginfo::DIScope; use rustc::ty::{self, Ty, TypeFoldable, UpvarSubsts}; use rustc::ty::layout::{LayoutOf, TyLayout}; use rustc::mir::{self, Mir}; @@ -29,7 +29,6 @@ use syntax_pos::{DUMMY_SP, NO_EXPANSION, BytePos, Span}; use syntax::symbol::keywords; use std::iter; -use std::ptr::NonNull; use rustc_data_structures::bitvec::BitVector; use rustc_data_structures::indexed_vec::{IndexVec, Idx}; @@ -48,7 +47,7 @@ pub struct FunctionCx<'a, 'll: 'a, 'tcx: 'll> { mir: &'a mir::Mir<'tcx>, - debug_context: debuginfo::FunctionDebugContext, + debug_context: FunctionDebugContext<'ll>, llfn: ValueRef, @@ -100,7 +99,7 @@ pub struct FunctionCx<'a, 'll: 'a, 'tcx: 'll> { locals: IndexVec>, /// Debug information for MIR scopes. - scopes: IndexVec, + scopes: IndexVec>, /// If this function is being monomorphized, this contains the type substitutions used. param_substs: &'tcx Substs<'tcx>, @@ -117,12 +116,12 @@ impl FunctionCx<'a, 'll, 'tcx> { ) } - pub fn set_debug_loc(&mut self, bx: &Builder, source_info: mir::SourceInfo) { + pub fn set_debug_loc(&mut self, bx: &Builder<'_, 'll, '_>, source_info: mir::SourceInfo) { let (scope, span) = self.debug_loc(source_info); debuginfo::set_source_location(&self.debug_context, bx, scope, span); } - pub fn debug_loc(&mut self, source_info: mir::SourceInfo) -> (Option>, Span) { + pub fn debug_loc(&mut self, source_info: mir::SourceInfo) -> (Option<&'ll DIScope>, Span) { // Bail out if debug info emission is not enabled. match self.debug_context { FunctionDebugContext::DebugInfoDisabled | @@ -162,14 +161,14 @@ impl FunctionCx<'a, 'll, 'tcx> { // corresponding to span's containing source scope. If so, we need to create a DIScope // "extension" into that file. fn scope_metadata_for_loc(&self, scope_id: mir::SourceScope, pos: BytePos) - -> Option> { + -> Option<&'ll DIScope> { let scope_metadata = self.scopes[scope_id].scope_metadata; if pos < self.scopes[scope_id].file_start_pos || pos >= self.scopes[scope_id].file_end_pos { let cm = self.cx.sess().codemap(); let defining_crate = self.debug_context.get_ref(DUMMY_SP).defining_crate; - NonNull::new(debuginfo::extend_scope_to_file(self.cx, - scope_metadata.unwrap().as_ptr(), + Some(debuginfo::extend_scope_to_file(self.cx, + scope_metadata.unwrap(), &cm.lookup_char_pos(pos).file, defining_crate)) } else { @@ -281,7 +280,7 @@ pub fn codegen_mir( span: decl.source_info.span, scope: decl.visibility_scope, }); - declare_local(&bx, &fx.debug_context, name, layout.ty, scope.unwrap().as_ptr(), + declare_local(&bx, &fx.debug_context, name, layout.ty, scope.unwrap(), VariableAccess::DirectVariable { alloca: place.llval }, VariableKind::LocalVariable, span); } @@ -416,7 +415,7 @@ fn create_funclets( fn arg_local_refs( bx: &Builder<'a, 'll, 'tcx>, fx: &FunctionCx<'a, 'll, 'tcx>, - scopes: &IndexVec, + scopes: &IndexVec>, memory_locals: &BitVector, ) -> Vec> { let mir = fx.mir; @@ -473,7 +472,7 @@ fn arg_local_refs( bx, &fx.debug_context, arg_decl.name.unwrap_or(keywords::Invalid.name()), - arg_ty, scope.as_ptr(), + arg_ty, scope, variable_access, VariableKind::ArgumentVariable(arg_index + 1), DUMMY_SP @@ -552,7 +551,7 @@ fn arg_local_refs( &fx.debug_context, arg_decl.name.unwrap_or(keywords::Invalid.name()), arg.layout.ty, - scope.as_ptr(), + scope, variable_access, VariableKind::ArgumentVariable(arg_index + 1), DUMMY_SP @@ -603,7 +602,7 @@ fn arg_local_refs( &fx.debug_context, decl.debug_name, ty, - scope.as_ptr(), + scope, variable_access, VariableKind::LocalVariable, DUMMY_SP diff --git a/src/librustc_codegen_llvm/type_.rs b/src/librustc_codegen_llvm/type_.rs index 4e3a82f0d74e5..9fa7cc46aee5e 100644 --- a/src/librustc_codegen_llvm/type_.rs +++ b/src/librustc_codegen_llvm/type_.rs @@ -14,7 +14,6 @@ pub use llvm::Type; use llvm; use llvm::{Bool, False, True, TypeKind}; -use llvm::{Float, Double, X86_FP80, PPC_FP128, FP128}; use context::CodegenCx; @@ -265,10 +264,10 @@ impl Type { pub fn float_width(&self) -> usize { match self.kind() { - Float => 32, - Double => 64, - X86_FP80 => 80, - FP128 | PPC_FP128 => 128, + TypeKind::Float => 32, + TypeKind::Double => 64, + TypeKind::X86_FP80 => 80, + TypeKind::FP128 | TypeKind::PPC_FP128 => 128, _ => bug!("llvm_float_width called on a non-float type") } } From 50d764298e1b7fdc193f0f66c1a692015c852227 Mon Sep 17 00:00:00 2001 From: Irina Popa Date: Wed, 4 Jul 2018 16:45:48 +0300 Subject: [PATCH 08/36] rustc_codegen_llvm: remove unused ExecutionEngineRef type. --- src/librustc_codegen_llvm/llvm/ffi.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index 389cfa1d7b107..613cc36b47f19 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -384,8 +384,6 @@ extern { pub type Metadata; } extern { pub type BasicBlock_opaque; } pub type BasicBlockRef = *mut BasicBlock_opaque; extern { pub type Builder; } -extern { pub type ExecutionEngine_opaque; } -pub type ExecutionEngineRef = *mut ExecutionEngine_opaque; extern { pub type MemoryBuffer_opaque; } pub type MemoryBufferRef = *mut MemoryBuffer_opaque; extern { pub type PassManager_opaque; } From 1da26707d6ef6eb703001157a7a9a7bd20d17c83 Mon Sep 17 00:00:00 2001 From: Irina Popa Date: Wed, 4 Jul 2018 19:16:13 +0300 Subject: [PATCH 09/36] rustc_codegen_llvm: remove #![allow(dead_code)] from llvm. --- src/librustc_codegen_llvm/llvm/archive_ro.rs | 4 +-- src/librustc_codegen_llvm/llvm/ffi.rs | 8 ------ src/librustc_codegen_llvm/llvm/mod.rs | 27 -------------------- 3 files changed, 2 insertions(+), 37 deletions(-) diff --git a/src/librustc_codegen_llvm/llvm/archive_ro.rs b/src/librustc_codegen_llvm/llvm/archive_ro.rs index 116f16de324be..e25f66919614c 100644 --- a/src/librustc_codegen_llvm/llvm/archive_ro.rs +++ b/src/librustc_codegen_llvm/llvm/archive_ro.rs @@ -25,8 +25,8 @@ pub struct ArchiveRO { unsafe impl Send for ArchiveRO {} pub struct Iter<'a> { - archive: &'a ArchiveRO, ptr: super::ArchiveIteratorRef, + _data: marker::PhantomData<&'a ArchiveRO>, } pub struct Child<'a> { @@ -73,7 +73,7 @@ impl ArchiveRO { unsafe { Iter { ptr: super::LLVMRustArchiveIteratorNew(self.ptr), - archive: self, + _data: marker::PhantomData, } } } diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index 613cc36b47f19..fcecb5c88c5f5 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -392,8 +392,6 @@ extern { pub type PassManagerBuilder_opaque; } pub type PassManagerBuilderRef = *mut PassManagerBuilder_opaque; extern { pub type Use_opaque; } pub type UseRef = *mut Use_opaque; -extern { pub type TargetData_opaque; } -pub type TargetDataRef = *mut TargetData_opaque; extern { pub type ObjectFile_opaque; } pub type ObjectFileRef = *mut ObjectFile_opaque; extern { pub type SectionIterator_opaque; } @@ -1264,12 +1262,6 @@ extern "C" { /// Writes a module to the specified path. Returns 0 on success. pub fn LLVMWriteBitcodeToFile(M: &Module, 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; diff --git a/src/librustc_codegen_llvm/llvm/mod.rs b/src/librustc_codegen_llvm/llvm/mod.rs index 37f1bf5c1e70f..98d8932e612c3 100644 --- a/src/librustc_codegen_llvm/llvm/mod.rs +++ b/src/librustc_codegen_llvm/llvm/mod.rs @@ -11,7 +11,6 @@ #![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::*; @@ -177,25 +176,6 @@ impl Attribute { } } -// 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 { @@ -254,13 +234,6 @@ pub fn get_param(llfn: ValueRef, index: c_uint) -> ValueRef { } } -fn get_params(llfn: ValueRef) -> Vec { - unsafe { - let num_params = LLVMCountParams(llfn); - (0..num_params).map(|idx| LLVMGetParam(llfn, idx)).collect() - } -} - pub fn build_string(f: F) -> Option where F: FnOnce(RustStringRef) { From 8d1768434168875e9ce2d4273ca1ed9e6f69d18f Mon Sep 17 00:00:00 2001 From: Irina Popa Date: Thu, 5 Jul 2018 13:38:44 +0300 Subject: [PATCH 10/36] rustc_codegen_llvm: remove _opaque suffix. --- src/librustc_codegen_llvm/llvm/ffi.rs | 94 +++++++++++++-------------- src/librustc_codegen_llvm/llvm/mod.rs | 4 +- 2 files changed, 49 insertions(+), 49 deletions(-) diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index fcecb5c88c5f5..63f09a7e53a20 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -378,48 +378,48 @@ pub enum ThreadLocalMode { extern { pub type Module; } extern { pub type Context; } extern { pub type Type; } -extern { pub type Value_opaque; } -pub type ValueRef = *mut Value_opaque; +extern { pub type Value; } +pub type ValueRef = *mut Value; extern { pub type Metadata; } -extern { pub type BasicBlock_opaque; } -pub type BasicBlockRef = *mut BasicBlock_opaque; +extern { pub type BasicBlock; } +pub type BasicBlockRef = *mut BasicBlock; extern { pub type Builder; } -extern { pub type MemoryBuffer_opaque; } -pub type MemoryBufferRef = *mut MemoryBuffer_opaque; -extern { pub type PassManager_opaque; } -pub type PassManagerRef = *mut PassManager_opaque; -extern { pub type PassManagerBuilder_opaque; } -pub type PassManagerBuilderRef = *mut PassManagerBuilder_opaque; -extern { pub type Use_opaque; } -pub type UseRef = *mut Use_opaque; -extern { pub type ObjectFile_opaque; } -pub type ObjectFileRef = *mut ObjectFile_opaque; -extern { pub type SectionIterator_opaque; } -pub type SectionIteratorRef = *mut SectionIterator_opaque; -extern { pub type Pass_opaque; } -pub type PassRef = *mut Pass_opaque; +extern { pub type MemoryBuffer; } +pub type MemoryBufferRef = *mut MemoryBuffer; +extern { pub type PassManager; } +pub type PassManagerRef = *mut PassManager; +extern { pub type PassManagerBuilder; } +pub type PassManagerBuilderRef = *mut PassManagerBuilder; +extern { pub type Use; } +pub type UseRef = *mut Use; +extern { pub type ObjectFile; } +pub type ObjectFileRef = *mut ObjectFile; +extern { pub type SectionIterator; } +pub type SectionIteratorRef = *mut SectionIterator; +extern { pub type Pass; } +pub type PassRef = *mut Pass; extern { pub type TargetMachine; } pub type TargetMachineRef = *const TargetMachine; -extern { pub type Archive_opaque; } -pub type ArchiveRef = *mut Archive_opaque; -extern { pub type ArchiveIterator_opaque; } -pub type ArchiveIteratorRef = *mut ArchiveIterator_opaque; -extern { pub type ArchiveChild_opaque; } -pub type ArchiveChildRef = *mut ArchiveChild_opaque; -extern { pub type Twine_opaque; } -pub type TwineRef = *mut Twine_opaque; -extern { pub type DiagnosticInfo_opaque; } -pub type DiagnosticInfoRef = *mut DiagnosticInfo_opaque; -extern { pub type DebugLoc_opaque; } -pub type DebugLocRef = *mut DebugLoc_opaque; -extern { pub type SMDiagnostic_opaque; } -pub type SMDiagnosticRef = *mut SMDiagnostic_opaque; -extern { pub type RustArchiveMember_opaque; } -pub type RustArchiveMemberRef = *mut RustArchiveMember_opaque; -extern { pub type OperandBundleDef_opaque; } -pub type OperandBundleDefRef = *mut OperandBundleDef_opaque; -extern { pub type Linker_opaque; } -pub type LinkerRef = *mut Linker_opaque; +extern { pub type Archive; } +pub type ArchiveRef = *mut Archive; +extern { pub type ArchiveIterator; } +pub type ArchiveIteratorRef = *mut ArchiveIterator; +extern { pub type ArchiveChild; } +pub type ArchiveChildRef = *mut ArchiveChild; +extern { pub type Twine; } +pub type TwineRef = *mut Twine; +extern { pub type DiagnosticInfo; } +pub type DiagnosticInfoRef = *mut DiagnosticInfo; +extern { pub type DebugLoc; } +pub type DebugLocRef = *mut DebugLoc; +extern { pub type SMDiagnostic; } +pub type SMDiagnosticRef = *mut SMDiagnostic; +extern { pub type RustArchiveMember; } +pub type RustArchiveMemberRef = *mut RustArchiveMember; +extern { pub type OperandBundleDef; } +pub type OperandBundleDefRef = *mut OperandBundleDef; +extern { pub type Linker; } +pub type LinkerRef = *mut Linker; pub type DiagnosticHandler = unsafe extern "C" fn(DiagnosticInfoRef, *mut c_void); pub type InlineAsmDiagHandler = unsafe extern "C" fn(SMDiagnosticRef, *const c_void, c_uint); @@ -552,7 +552,7 @@ extern "C" { pub fn LLVMRustMetadataTypeInContext(C: &Context) -> &Type; // Operations on all values - pub fn LLVMTypeOf(Val: &Value_opaque) -> &Type; + pub fn LLVMTypeOf(Val: &Value) -> &Type; pub fn LLVMGetValueName(Val: ValueRef) -> *const c_char; pub fn LLVMSetValueName(Val: ValueRef, Name: *const c_char); pub fn LLVMReplaceAllUsesWith(OldVal: ValueRef, NewVal: ValueRef); @@ -758,7 +758,7 @@ extern "C" { pub fn LLVMDisposeBuilder(Builder: &Builder); // Metadata - pub fn LLVMSetCurrentDebugLocation(Builder: &Builder, L: Option>); + pub fn LLVMSetCurrentDebugLocation(Builder: &Builder, L: Option>); pub fn LLVMGetCurrentDebugLocation(Builder: &Builder) -> ValueRef; pub fn LLVMSetInstDebugLocation(Builder: &Builder, Inst: ValueRef); @@ -784,7 +784,7 @@ extern "C" { NumArgs: c_uint, Then: BasicBlockRef, Catch: BasicBlockRef, - Bundle: Option>, + Bundle: Option>, Name: *const c_char) -> ValueRef; pub fn LLVMBuildLandingPad(B: &'a Builder, @@ -797,14 +797,14 @@ extern "C" { pub fn LLVMBuildUnreachable(B: &Builder) -> ValueRef; pub fn LLVMRustBuildCleanupPad(B: &Builder, - ParentPad: Option>, + ParentPad: Option>, ArgCnt: c_uint, Args: *const ValueRef, Name: *const c_char) -> ValueRef; pub fn LLVMRustBuildCleanupRet(B: &Builder, CleanupPad: ValueRef, - UnwindBB: Option>) + UnwindBB: Option>) -> ValueRef; pub fn LLVMRustBuildCatchPad(B: &Builder, ParentPad: ValueRef, @@ -814,8 +814,8 @@ extern "C" { -> ValueRef; pub fn LLVMRustBuildCatchRet(B: &Builder, Pad: ValueRef, BB: BasicBlockRef) -> ValueRef; pub fn LLVMRustBuildCatchSwitch(Builder: &Builder, - ParentPad: Option>, - BB: Option>, + ParentPad: Option>, + BB: Option>, NumHandlers: c_uint, Name: *const c_char) -> ValueRef; @@ -1126,7 +1126,7 @@ extern "C" { Fn: ValueRef, Args: *const ValueRef, NumArgs: c_uint, - Bundle: Option>, + Bundle: Option>, Name: *const c_char) -> ValueRef; pub fn LLVMBuildSelect(B: &Builder, @@ -1680,7 +1680,7 @@ extern "C" { -> LLVMRustResult; pub fn LLVMRustArchiveMemberNew(Filename: *const c_char, Name: *const c_char, - Child: Option>) + Child: Option>) -> RustArchiveMemberRef; pub fn LLVMRustArchiveMemberFree(Member: RustArchiveMemberRef); diff --git a/src/librustc_codegen_llvm/llvm/mod.rs b/src/librustc_codegen_llvm/llvm/mod.rs index 98d8932e612c3..cf06e9532216a 100644 --- a/src/librustc_codegen_llvm/llvm/mod.rs +++ b/src/librustc_codegen_llvm/llvm/mod.rs @@ -93,8 +93,8 @@ impl FromStr for ArchiveKind { } #[allow(missing_copy_implementations)] -pub enum RustString_opaque {} -type RustStringRef = *mut RustString_opaque; +extern { pub type RustString; } +type RustStringRef = *mut RustString; type RustStringRepr = *mut RefCell>; /// Appending to a Rust string -- used by RawRustStringOstream. From f375185314e94a266f76ad7ffdd61b2d4608e97d Mon Sep 17 00:00:00 2001 From: Irina Popa Date: Tue, 10 Jul 2018 13:28:39 +0300 Subject: [PATCH 11/36] rustc_codegen_llvm: use safe references for Value. --- src/librustc_codegen_llvm/abi.rs | 63 +- src/librustc_codegen_llvm/asm.rs | 9 +- src/librustc_codegen_llvm/attributes.rs | 20 +- src/librustc_codegen_llvm/base.rs | 120 +-- src/librustc_codegen_llvm/builder.rs | 452 ++++----- src/librustc_codegen_llvm/callee.rs | 21 +- src/librustc_codegen_llvm/common.rs | 91 +- src/librustc_codegen_llvm/consts.rs | 44 +- src/librustc_codegen_llvm/context.rs | 42 +- src/librustc_codegen_llvm/debuginfo/gdb.rs | 13 +- .../debuginfo/metadata.rs | 21 +- src/librustc_codegen_llvm/debuginfo/mod.rs | 12 +- .../debuginfo/source_loc.rs | 3 +- src/librustc_codegen_llvm/declare.rs | 58 +- src/librustc_codegen_llvm/glue.rs | 15 +- src/librustc_codegen_llvm/intrinsic.rs | 77 +- src/librustc_codegen_llvm/llvm/diagnostic.rs | 65 +- src/librustc_codegen_llvm/llvm/ffi.rs | 923 +++++++++--------- src/librustc_codegen_llvm/llvm/mod.rs | 28 +- src/librustc_codegen_llvm/meth.rs | 22 +- src/librustc_codegen_llvm/mir/analyze.rs | 2 +- src/librustc_codegen_llvm/mir/block.rs | 48 +- src/librustc_codegen_llvm/mir/constant.rs | 25 +- src/librustc_codegen_llvm/mir/mod.rs | 29 +- src/librustc_codegen_llvm/mir/operand.rs | 75 +- src/librustc_codegen_llvm/mir/place.rs | 81 +- src/librustc_codegen_llvm/mir/rvalue.rs | 68 +- src/librustc_codegen_llvm/value.rs | 21 +- 28 files changed, 1216 insertions(+), 1232 deletions(-) diff --git a/src/librustc_codegen_llvm/abi.rs b/src/librustc_codegen_llvm/abi.rs index 1d6214ab74093..44982eee86b3c 100644 --- a/src/librustc_codegen_llvm/abi.rs +++ b/src/librustc_codegen_llvm/abi.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use llvm::{self, ValueRef, AttributePlace}; +use llvm::{self, AttributePlace}; use base; use builder::{Builder, MemFlags}; use common::{ty_fn_sig, C_usize}; @@ -17,6 +17,7 @@ use mir::place::PlaceRef; use mir::operand::OperandValue; use type_::Type; use type_of::{LayoutLlvmExt, PointerKind}; +use value::Value; use rustc_target::abi::{LayoutOf, Size, TyLayout}; use rustc::ty::{self, Ty}; @@ -46,12 +47,12 @@ impl ArgAttributeExt for ArgAttribute { } pub trait ArgAttributesExt { - fn apply_llfn(&self, idx: AttributePlace, llfn: ValueRef); - fn apply_callsite(&self, idx: AttributePlace, callsite: ValueRef); + fn apply_llfn(&self, idx: AttributePlace, llfn: &Value); + fn apply_callsite(&self, idx: AttributePlace, callsite: &Value); } impl ArgAttributesExt for ArgAttributes { - fn apply_llfn(&self, idx: AttributePlace, llfn: ValueRef) { + fn apply_llfn(&self, idx: AttributePlace, llfn: &Value) { let mut regular = self.regular; unsafe { let deref = self.pointee_size.bytes(); @@ -76,7 +77,7 @@ impl ArgAttributesExt for ArgAttributes { } } - fn apply_callsite(&self, idx: AttributePlace, callsite: ValueRef) { + fn apply_callsite(&self, idx: AttributePlace, callsite: &Value) { let mut regular = self.regular; unsafe { let deref = self.pointee_size.bytes(); @@ -164,16 +165,16 @@ impl LlvmType for CastTarget { } } -pub trait ArgTypeExt<'a, 'tcx> { - fn memory_ty(&self, cx: &CodegenCx<'a, 'tcx>) -> &'a Type; - fn store(&self, bx: &Builder<'a, 'll, 'tcx>, val: ValueRef, dst: PlaceRef<'tcx>); - fn store_fn_arg(&self, bx: &Builder<'a, 'll, 'tcx>, idx: &mut usize, dst: PlaceRef<'tcx>); +pub trait ArgTypeExt<'ll, 'tcx> { + fn memory_ty(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type; + fn store(&self, bx: &Builder<'_, 'll, 'tcx>, val: &'ll Value, dst: PlaceRef<'ll, 'tcx>); + fn store_fn_arg(&self, bx: &Builder<'_, 'll, 'tcx>, idx: &mut usize, dst: PlaceRef<'ll, 'tcx>); } -impl<'a, 'tcx> ArgTypeExt<'a, 'tcx> for ArgType<'tcx, Ty<'tcx>> { +impl ArgTypeExt<'ll, 'tcx> for ArgType<'tcx, Ty<'tcx>> { /// Get the LLVM type for a place of the original Rust type of /// this argument/return, i.e. the result of `type_of::type_of`. - fn memory_ty(&self, cx: &CodegenCx<'a, 'tcx>) -> &'a Type { + fn memory_ty(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type { self.layout.llvm_type(cx) } @@ -181,7 +182,7 @@ impl<'a, 'tcx> ArgTypeExt<'a, 'tcx> for ArgType<'tcx, Ty<'tcx>> { /// place for the original Rust type of this argument/return. /// Can be used for both storing formal arguments into Rust variables /// or results of call/invoke instructions into their destinations. - fn store(&self, bx: &Builder<'a, 'll, 'tcx>, val: ValueRef, dst: PlaceRef<'tcx>) { + fn store(&self, bx: &Builder<'_, 'll, 'tcx>, val: &'ll Value, dst: PlaceRef<'ll, 'tcx>) { if self.is_ignore() { return; } @@ -234,7 +235,7 @@ impl<'a, 'tcx> ArgTypeExt<'a, 'tcx> for ArgType<'tcx, Ty<'tcx>> { } } - fn store_fn_arg(&self, bx: &Builder<'a, 'll, 'tcx>, idx: &mut usize, dst: PlaceRef<'tcx>) { + fn store_fn_arg(&self, bx: &Builder<'a, 'll, 'tcx>, idx: &mut usize, dst: PlaceRef<'ll, 'tcx>) { let mut next = || { let val = llvm::get_param(bx.llfn(), *idx as c_uint); *idx += 1; @@ -252,32 +253,32 @@ impl<'a, 'tcx> ArgTypeExt<'a, 'tcx> for ArgType<'tcx, Ty<'tcx>> { } } -pub trait FnTypeExt<'a, 'tcx> { - fn of_instance(cx: &CodegenCx<'a, 'tcx>, instance: &ty::Instance<'tcx>) +pub trait FnTypeExt<'tcx> { + fn of_instance(cx: &CodegenCx<'ll, 'tcx>, instance: &ty::Instance<'tcx>) -> Self; - fn new(cx: &CodegenCx<'a, 'tcx>, + fn new(cx: &CodegenCx<'ll, 'tcx>, sig: ty::FnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> Self; - fn new_vtable(cx: &CodegenCx<'a, 'tcx>, + fn new_vtable(cx: &CodegenCx<'ll, 'tcx>, sig: ty::FnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> Self; fn new_internal( - cx: &CodegenCx<'a, 'tcx>, + cx: &CodegenCx<'ll, 'tcx>, sig: ty::FnSig<'tcx>, extra_args: &[Ty<'tcx>], mk_arg_type: impl Fn(Ty<'tcx>, Option) -> ArgType<'tcx, Ty<'tcx>>, ) -> Self; fn adjust_for_abi(&mut self, - cx: &CodegenCx<'a, 'tcx>, + cx: &CodegenCx<'ll, 'tcx>, abi: Abi); - fn llvm_type(&self, cx: &CodegenCx<'a, 'tcx>) -> &'a Type; + fn llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type; fn llvm_cconv(&self) -> llvm::CallConv; - fn apply_attrs_llfn(&self, llfn: ValueRef); - fn apply_attrs_callsite(&self, bx: &Builder<'a, 'll, 'tcx>, callsite: ValueRef); + fn apply_attrs_llfn(&self, llfn: &'ll Value); + fn apply_attrs_callsite(&self, bx: &Builder<'a, 'll, 'tcx>, callsite: &'ll Value); } -impl<'a, 'tcx> FnTypeExt<'a, 'tcx> for FnType<'tcx, Ty<'tcx>> { - fn of_instance(cx: &CodegenCx<'a, 'tcx>, instance: &ty::Instance<'tcx>) +impl<'tcx> FnTypeExt<'tcx> for FnType<'tcx, Ty<'tcx>> { + fn of_instance(cx: &CodegenCx<'ll, 'tcx>, instance: &ty::Instance<'tcx>) -> Self { let fn_ty = instance.ty(cx.tcx); let sig = ty_fn_sig(cx, fn_ty); @@ -285,7 +286,7 @@ impl<'a, 'tcx> FnTypeExt<'a, 'tcx> for FnType<'tcx, Ty<'tcx>> { FnType::new(cx, sig, &[]) } - fn new(cx: &CodegenCx<'a, 'tcx>, + fn new(cx: &CodegenCx<'ll, 'tcx>, sig: ty::FnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> Self { FnType::new_internal(cx, sig, extra_args, |ty, _| { @@ -293,7 +294,7 @@ impl<'a, 'tcx> FnTypeExt<'a, 'tcx> for FnType<'tcx, Ty<'tcx>> { }) } - fn new_vtable(cx: &CodegenCx<'a, 'tcx>, + fn new_vtable(cx: &CodegenCx<'ll, 'tcx>, sig: ty::FnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> Self { FnType::new_internal(cx, sig, extra_args, |ty, arg_idx| { @@ -316,7 +317,7 @@ impl<'a, 'tcx> FnTypeExt<'a, 'tcx> for FnType<'tcx, Ty<'tcx>> { } fn new_internal( - cx: &CodegenCx<'a, 'tcx>, + cx: &CodegenCx<'ll, 'tcx>, sig: ty::FnSig<'tcx>, extra_args: &[Ty<'tcx>], mk_arg_type: impl Fn(Ty<'tcx>, Option) -> ArgType<'tcx, Ty<'tcx>>, @@ -497,7 +498,7 @@ impl<'a, 'tcx> FnTypeExt<'a, 'tcx> for FnType<'tcx, Ty<'tcx>> { } fn adjust_for_abi(&mut self, - cx: &CodegenCx<'a, 'tcx>, + cx: &CodegenCx<'ll, 'tcx>, abi: Abi) { if abi == Abi::Unadjusted { return } @@ -564,7 +565,7 @@ impl<'a, 'tcx> FnTypeExt<'a, 'tcx> for FnType<'tcx, Ty<'tcx>> { } } - fn llvm_type(&self, cx: &CodegenCx<'a, 'tcx>) -> &'a Type { + fn llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type { let args_capacity: usize = self.args.iter().map(|arg| if arg.pad.is_some() { 1 } else { 0 } + if let PassMode::Pair(_, _) = arg.mode { 2 } else { 1 } @@ -629,7 +630,7 @@ impl<'a, 'tcx> FnTypeExt<'a, 'tcx> for FnType<'tcx, Ty<'tcx>> { } } - fn apply_attrs_llfn(&self, llfn: ValueRef) { + fn apply_attrs_llfn(&self, llfn: &'ll Value) { let mut i = 0; let mut apply = |attrs: &ArgAttributes| { attrs.apply_llfn(llvm::AttributePlace::Argument(i), llfn); @@ -659,7 +660,7 @@ impl<'a, 'tcx> FnTypeExt<'a, 'tcx> for FnType<'tcx, Ty<'tcx>> { } } - fn apply_attrs_callsite(&self, bx: &Builder<'a, 'll, 'tcx>, callsite: ValueRef) { + fn apply_attrs_callsite(&self, bx: &Builder<'a, 'll, 'tcx>, callsite: &'ll Value) { let mut i = 0; let mut apply = |attrs: &ArgAttributes| { attrs.apply_callsite(llvm::AttributePlace::Argument(i), callsite); diff --git a/src/librustc_codegen_llvm/asm.rs b/src/librustc_codegen_llvm/asm.rs index c046b98685a77..5d27f8eab3ece 100644 --- a/src/librustc_codegen_llvm/asm.rs +++ b/src/librustc_codegen_llvm/asm.rs @@ -8,11 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use llvm::{self, ValueRef}; +use llvm; use common::*; use type_::Type; use type_of::LayoutLlvmExt; use builder::Builder; +use value::Value; use rustc::hir; @@ -27,8 +28,8 @@ use libc::{c_uint, c_char}; pub fn codegen_inline_asm( bx: &Builder<'a, 'll, 'tcx>, ia: &hir::InlineAsm, - outputs: Vec>, - mut inputs: Vec + outputs: Vec>, + mut inputs: Vec<&'ll Value> ) { let mut ext_constraints = vec![]; let mut output_types = vec![]; @@ -111,7 +112,7 @@ pub fn codegen_inline_asm( let kind = llvm::LLVMGetMDKindIDInContext(bx.cx.llcx, key.as_ptr() as *const c_char, key.len() as c_uint); - let val: llvm::ValueRef = C_i32(bx.cx, ia.ctxt.outer().as_u32() as i32); + let val: &'ll Value = C_i32(bx.cx, ia.ctxt.outer().as_u32() as i32); llvm::LLVMSetMetadata(r, kind, llvm::LLVMMDNodeInContext(bx.cx.llcx, &val, 1)); diff --git a/src/librustc_codegen_llvm/attributes.rs b/src/librustc_codegen_llvm/attributes.rs index 3b5f927d52f00..c52f894410899 100644 --- a/src/librustc_codegen_llvm/attributes.rs +++ b/src/librustc_codegen_llvm/attributes.rs @@ -22,15 +22,17 @@ use rustc_data_structures::fx::FxHashMap; use rustc_target::spec::PanicStrategy; use attributes; -use llvm::{self, Attribute, ValueRef}; +use llvm::{self, Attribute}; use llvm::AttributePlace::Function; use llvm_util; pub use syntax::attr::{self, InlineAttr}; + use context::CodegenCx; +use value::Value; /// Mark LLVM function to use provided inline heuristic. #[inline] -pub fn inline(val: ValueRef, inline: InlineAttr) { +pub fn inline(val: &'ll Value, inline: InlineAttr) { use self::InlineAttr::*; match inline { Hint => Attribute::InlineHint.apply_llfn(Function, val), @@ -46,30 +48,30 @@ pub fn inline(val: ValueRef, inline: InlineAttr) { /// Tell LLVM to emit or not emit the information necessary to unwind the stack for the function. #[inline] -pub fn emit_uwtable(val: ValueRef, emit: bool) { +pub fn emit_uwtable(val: &'ll Value, emit: bool) { Attribute::UWTable.toggle_llfn(Function, val, emit); } /// Tell LLVM whether the function can or cannot unwind. #[inline] -pub fn unwind(val: ValueRef, can_unwind: bool) { +pub fn unwind(val: &'ll Value, can_unwind: bool) { Attribute::NoUnwind.toggle_llfn(Function, val, !can_unwind); } /// Tell LLVM whether it should optimize function for size. #[inline] #[allow(dead_code)] // possibly useful function -pub fn set_optimize_for_size(val: ValueRef, optimize: bool) { +pub fn set_optimize_for_size(val: &'ll Value, optimize: bool) { Attribute::OptimizeForSize.toggle_llfn(Function, val, optimize); } /// Tell LLVM if this function should be 'naked', i.e. skip the epilogue and prologue. #[inline] -pub fn naked(val: ValueRef, is_naked: bool) { +pub fn naked(val: &'ll Value, is_naked: bool) { Attribute::Naked.toggle_llfn(Function, val, is_naked); } -pub fn set_frame_pointer_elimination(cx: &CodegenCx, llfn: ValueRef) { +pub fn set_frame_pointer_elimination(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) { if cx.sess().must_not_eliminate_frame_pointers() { llvm::AddFunctionAttrStringValue( llfn, llvm::AttributePlace::Function, @@ -77,7 +79,7 @@ pub fn set_frame_pointer_elimination(cx: &CodegenCx, llfn: ValueRef) { } } -pub fn set_probestack(cx: &CodegenCx, llfn: ValueRef) { +pub fn set_probestack(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) { // Only use stack probes if the target specification indicates that we // should be using stack probes if !cx.sess().target.target.options.stack_probes { @@ -123,7 +125,7 @@ pub fn llvm_target_features(sess: &Session) -> impl Iterator { /// Composite function which sets LLVM attributes for function depending on its AST (#[attribute]) /// attributes. -pub fn from_fn_attrs(cx: &CodegenCx, llfn: ValueRef, id: DefId) { +pub fn from_fn_attrs(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value, id: DefId) { let codegen_fn_attrs = cx.tcx.codegen_fn_attrs(id); inline(llfn, codegen_fn_attrs.inline); diff --git a/src/librustc_codegen_llvm/base.rs b/src/librustc_codegen_llvm/base.rs index f6fdf18dd94df..40115266e2e2a 100644 --- a/src/librustc_codegen_llvm/base.rs +++ b/src/librustc_codegen_llvm/base.rs @@ -17,7 +17,7 @@ //! //! Hopefully useful general knowledge about codegen: //! -//! * There's no way to find out the Ty type of a ValueRef. Doing so +//! * There's no way to find out the Ty type of a Value. Doing so //! would be "trying to get the eggs out of an omelette" (credit: //! pcwalton). You can, instead, find out its llvm::Type by calling val_ty, //! but one llvm::Type corresponds to many `Ty`s; for instance, tup(int, int, @@ -31,8 +31,7 @@ use super::ModuleKind; use abi; use back::link; use back::write::{self, OngoingCodegen}; -use llvm::{TypeKind, ValueRef, get_param}; -use llvm; +use llvm::{self, TypeKind, get_param}; use metadata; use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use rustc::middle::lang_items::StartFnLangItem; @@ -87,6 +86,8 @@ use syntax_pos::symbol::InternedString; use syntax::attr; use rustc::hir::{self, CodegenFnAttrs}; +use value::Value; + use mir::operand::OperandValue; use rustc_codegen_utils::check_for_rustc_errors_attr; @@ -157,12 +158,12 @@ pub fn bin_op_to_fcmp_predicate(op: hir::BinOpKind) -> llvm::RealPredicate { pub fn compare_simd_types( bx: &Builder<'a, 'll, 'tcx>, - lhs: ValueRef, - rhs: ValueRef, + lhs: &'ll Value, + rhs: &'ll Value, t: Ty<'tcx>, ret_ty: &'ll Type, op: hir::BinOpKind -) -> ValueRef { +) -> &'ll Value { let signed = match t.sty { ty::TyFloat(_) => { let cmp = bin_op_to_fcmp_predicate(op); @@ -187,11 +188,12 @@ pub fn compare_simd_types( /// The `old_info` argument is a bit funny. It is intended for use /// in an upcast, where the new vtable for an object will be derived /// from the old one. -pub fn unsized_info<'cx, 'tcx>(cx: &CodegenCx<'cx, 'tcx>, - source: Ty<'tcx>, - target: Ty<'tcx>, - old_info: Option) - -> ValueRef { +pub fn unsized_info( + cx: &CodegenCx<'ll, 'tcx>, + source: Ty<'tcx>, + target: Ty<'tcx>, + old_info: Option<&'ll Value>, +) -> &'ll Value { let (source, target) = cx.tcx.struct_lockstep_tails(source, target); match (&source.sty, &target.sty) { (&ty::TyArray(_, len), &ty::TySlice(_)) => { @@ -218,10 +220,10 @@ pub fn unsized_info<'cx, 'tcx>(cx: &CodegenCx<'cx, 'tcx>, /// Coerce `src` to `dst_ty`. `src_ty` must be a thin pointer. pub fn unsize_thin_ptr( bx: &Builder<'a, 'll, 'tcx>, - src: ValueRef, + src: &'ll Value, src_ty: Ty<'tcx>, dst_ty: Ty<'tcx> -) -> (ValueRef, ValueRef) { +) -> (&'ll Value, &'ll Value) { debug!("unsize_thin_ptr: {:?} => {:?}", src_ty, dst_ty); match (&src_ty.sty, &dst_ty.sty) { (&ty::TyRef(_, a, _), @@ -273,8 +275,8 @@ pub fn unsize_thin_ptr( /// to a value of type `dst_ty` and store the result in `dst` pub fn coerce_unsized_into( bx: &Builder<'a, 'll, 'tcx>, - src: PlaceRef<'tcx>, - dst: PlaceRef<'tcx> + src: PlaceRef<'ll, 'tcx>, + dst: PlaceRef<'ll, 'tcx> ) { let src_ty = src.layout.ty; let dst_ty = dst.layout.ty; @@ -331,19 +333,19 @@ pub fn coerce_unsized_into( } pub fn cast_shift_expr_rhs( - cx: &Builder, op: hir::BinOpKind, lhs: ValueRef, rhs: ValueRef -) -> ValueRef { + cx: &Builder<'_, 'll, '_>, op: hir::BinOpKind, lhs: &'ll Value, rhs: &'ll Value +) -> &'ll Value { cast_shift_rhs(op, lhs, rhs, |a, b| cx.trunc(a, b), |a, b| cx.zext(a, b)) } fn cast_shift_rhs<'ll, F, G>(op: hir::BinOpKind, - lhs: ValueRef, - rhs: ValueRef, + lhs: &'ll Value, + rhs: &'ll Value, trunc: F, zext: G) - -> ValueRef - where F: FnOnce(ValueRef, &'ll Type) -> ValueRef, - G: FnOnce(ValueRef, &'ll Type) -> ValueRef + -> &'ll Value + where F: FnOnce(&'ll Value, &'ll Type) -> &'ll Value, + G: FnOnce(&'ll Value, &'ll Type) -> &'ll Value { // Shifts may have any size int on the rhs if op.is_shift() { @@ -380,12 +382,12 @@ pub fn wants_msvc_seh(sess: &Session) -> bool { sess.target.target.options.is_like_msvc } -pub fn call_assume(bx: &Builder<'a, 'll, 'tcx>, val: ValueRef) { +pub fn call_assume(bx: &Builder<'_, 'll, '_>, val: &'ll Value) { let assume_intrinsic = bx.cx.get_intrinsic("llvm.assume"); bx.call(assume_intrinsic, &[val], None); } -pub fn from_immediate(bx: &Builder, val: ValueRef) -> ValueRef { +pub fn from_immediate(bx: &Builder<'_, 'll, '_>, val: &'ll Value) -> &'ll Value { if val_ty(val) == Type::i1(bx.cx) { bx.zext(val, Type::i8(bx.cx)) } else { @@ -393,26 +395,28 @@ pub fn from_immediate(bx: &Builder, val: ValueRef) -> ValueRef { } } -pub fn to_immediate(bx: &Builder, val: ValueRef, layout: layout::TyLayout) -> ValueRef { +pub fn to_immediate(bx: &Builder<'_, 'll, '_>, val: &'ll Value, layout: layout::TyLayout) -> &'ll Value { if let layout::Abi::Scalar(ref scalar) = layout.abi { return to_immediate_scalar(bx, val, scalar); } val } -pub fn to_immediate_scalar(bx: &Builder, val: ValueRef, scalar: &layout::Scalar) -> ValueRef { +pub fn to_immediate_scalar(bx: &Builder<'_, 'll, '_>, val: &'ll Value, scalar: &layout::Scalar) -> &'ll Value { if scalar.is_bool() { return bx.trunc(val, Type::i1(bx.cx)); } val } -pub fn call_memcpy(bx: &Builder, - dst: ValueRef, - src: ValueRef, - n_bytes: ValueRef, - align: Align, - flags: MemFlags) { +pub fn call_memcpy( + bx: &Builder<'_, 'll, '_>, + dst: &'ll Value, + src: &'ll Value, + n_bytes: &'ll Value, + align: Align, + flags: MemFlags, +) { if flags.contains(MemFlags::NONTEMPORAL) { // HACK(nox): This is inefficient but there is no nontemporal memcpy. let val = bx.load(src, align); @@ -433,9 +437,9 @@ pub fn call_memcpy(bx: &Builder, } pub fn memcpy_ty( - bx: &Builder<'a, 'll, 'tcx>, - dst: ValueRef, - src: ValueRef, + bx: &Builder<'_, 'll, 'tcx>, + dst: &'ll Value, + src: &'ll Value, layout: TyLayout<'tcx>, align: Align, flags: MemFlags, @@ -449,13 +453,13 @@ pub fn memcpy_ty( } pub fn call_memset( - bx: &Builder<'a, 'll, 'tcx>, - ptr: ValueRef, - fill_byte: ValueRef, - size: ValueRef, - align: ValueRef, + bx: &Builder<'_, 'll, '_>, + ptr: &'ll Value, + fill_byte: &'ll Value, + size: &'ll Value, + align: &'ll Value, volatile: bool, -) -> ValueRef { +) -> &'ll Value { let ptr_width = &bx.cx.sess().target.target.target_pointer_width; let intrinsic_key = format!("llvm.memset.p0i8.i{}", ptr_width); let llintrinsicfn = bx.cx.get_intrinsic(&intrinsic_key); @@ -514,7 +518,7 @@ pub fn codegen_instance<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, instance: Instance<' mir::codegen_mir(cx, lldecl, &mir, instance, sig); } -pub fn set_link_section(llval: ValueRef, attrs: &CodegenFnAttrs) { +pub fn set_link_section(llval: &Value, attrs: &CodegenFnAttrs) { let sect = match attrs.link_section { Some(name) => name, None => return, @@ -552,11 +556,13 @@ fn maybe_create_entry_wrapper(cx: &CodegenCx) { None => {} // Do nothing. } - fn create_entry_fn<'cx>(cx: &'cx CodegenCx, - sp: Span, - rust_main: ValueRef, - rust_main_def_id: DefId, - use_start_lang_item: bool) { + fn create_entry_fn( + cx: &CodegenCx<'ll, '_>, + sp: Span, + rust_main: &'ll Value, + rust_main_def_id: DefId, + use_start_lang_item: bool, + ) { let llfty = Type::func(&[Type::c_int(cx), Type::i8p(cx).ptr_to()], Type::c_int(cx)); let main_ret_ty = cx.tcx.fn_sig(rust_main_def_id).output(); @@ -678,26 +684,24 @@ fn write_metadata<'a, 'gcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>, return metadata; } -pub struct ValueIter { - cur: ValueRef, - step: unsafe extern "C" fn(ValueRef) -> ValueRef, +pub struct ValueIter<'ll> { + cur: Option<&'ll Value>, + step: unsafe extern "C" fn(&'ll Value) -> Option<&'ll Value>, } -impl Iterator for ValueIter { - type Item = ValueRef; +impl Iterator for ValueIter<'ll> { + type Item = &'ll Value; - fn next(&mut self) -> Option { + fn next(&mut self) -> Option<&'ll Value> { let old = self.cur; - if !old.is_null() { + if let Some(old) = old { self.cur = unsafe { (self.step)(old) }; - Some(old) - } else { - None } + old } } -pub fn iter_globals(llmod: &llvm::Module) -> ValueIter { +pub fn iter_globals(llmod: &'ll llvm::Module) -> ValueIter<'ll> { unsafe { ValueIter { cur: llvm::LLVMGetFirstGlobal(llmod), diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index 841b0add89b73..19ae990fa65ff 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -10,10 +10,9 @@ #![allow(dead_code)] // FFI wrappers -use llvm; use llvm::{AtomicRmwBinOp, AtomicOrdering, SynchronizationScope, AsmDialect}; use llvm::{Opcode, IntPredicate, RealPredicate, False, OperandBundleDef}; -use llvm::{ValueRef, BasicBlockRef}; +use llvm::{self, BasicBlockRef}; use common::*; use type_::Type; use value::Value; @@ -60,7 +59,7 @@ bitflags! { } impl Builder<'a, 'll, 'tcx> { - pub fn new_block<'b>(cx: &'a CodegenCx<'ll, 'tcx>, llfn: ValueRef, name: &'b str) -> Self { + pub fn new_block<'b>(cx: &'a CodegenCx<'ll, 'tcx>, llfn: &'ll Value, name: &'b str) -> Self { let bx = Builder::with_cx(cx); let llbb = unsafe { let name = CString::new(name).unwrap(); @@ -97,7 +96,7 @@ impl Builder<'a, 'll, 'tcx> { self.cx.tcx } - pub fn llfn(&self) -> ValueRef { + pub fn llfn(&self) -> &'ll Value { unsafe { llvm::LLVMGetBasicBlockParent(self.llbb()) } @@ -122,14 +121,14 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn set_value_name(&self, value: ValueRef, name: &str) { + pub fn set_value_name(&self, value: &'ll Value, name: &str) { let cname = CString::new(name.as_bytes()).unwrap(); unsafe { llvm::LLVMSetValueName(value, cname.as_ptr()); } } - pub fn position_before(&self, insn: ValueRef) { + pub fn position_before(&self, insn: &'ll Value) { unsafe { llvm::LLVMPositionBuilderBefore(self.llbuilder, insn); } @@ -154,14 +153,14 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn ret(&self, v: ValueRef) { + pub fn ret(&self, v: &'ll Value) { self.count_insn("ret"); unsafe { llvm::LLVMBuildRet(self.llbuilder, v); } } - pub fn aggregate_ret(&self, ret_vals: &[ValueRef]) { + pub fn aggregate_ret(&self, ret_vals: &[&'ll Value]) { unsafe { llvm::LLVMBuildAggregateRet(self.llbuilder, ret_vals.as_ptr(), @@ -176,20 +175,20 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn cond_br(&self, cond: ValueRef, then_llbb: BasicBlockRef, else_llbb: BasicBlockRef) { + pub fn cond_br(&self, cond: &'ll Value, then_llbb: BasicBlockRef, else_llbb: BasicBlockRef) { self.count_insn("condbr"); unsafe { llvm::LLVMBuildCondBr(self.llbuilder, cond, then_llbb, else_llbb); } } - pub fn switch(&self, v: ValueRef, else_llbb: BasicBlockRef, num_cases: usize) -> ValueRef { + pub fn switch(&self, v: &'ll Value, else_llbb: BasicBlockRef, num_cases: usize) -> &'ll Value { unsafe { llvm::LLVMBuildSwitch(self.llbuilder, v, else_llbb, num_cases as c_uint) } } - pub fn indirect_br(&self, addr: ValueRef, num_dests: usize) { + pub fn indirect_br(&self, addr: &'ll Value, num_dests: usize) { self.count_insn("indirectbr"); unsafe { llvm::LLVMBuildIndirectBr(self.llbuilder, addr, num_dests as c_uint); @@ -197,19 +196,16 @@ impl Builder<'a, 'll, 'tcx> { } pub fn invoke(&self, - llfn: ValueRef, - args: &[ValueRef], + llfn: &'ll Value, + args: &[&'ll Value], then: BasicBlockRef, catch: BasicBlockRef, - bundle: Option<&OperandBundleDef>) -> ValueRef { + bundle: Option<&OperandBundleDef>) -> &'ll Value { self.count_insn("invoke"); - debug!("Invoke {:?} with args ({})", - Value(llfn), - args.iter() - .map(|&v| format!("{:?}", Value(v))) - .collect::>() - .join(", ")); + debug!("Invoke {:?} with args ({:?})", + llfn, + args); let args = self.check_call("invoke", llfn, args); let bundle = bundle.as_ref().and_then(|b| NonNull::new(b.raw())); @@ -234,35 +230,35 @@ impl Builder<'a, 'll, 'tcx> { } /* Arithmetic */ - pub fn add(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef { + pub fn add(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { self.count_insn("add"); unsafe { llvm::LLVMBuildAdd(self.llbuilder, lhs, rhs, noname()) } } - pub fn nswadd(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef { + pub fn nswadd(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { self.count_insn("nswadd"); unsafe { llvm::LLVMBuildNSWAdd(self.llbuilder, lhs, rhs, noname()) } } - pub fn nuwadd(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef { + pub fn nuwadd(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { self.count_insn("nuwadd"); unsafe { llvm::LLVMBuildNUWAdd(self.llbuilder, lhs, rhs, noname()) } } - pub fn fadd(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef { + pub fn fadd(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { self.count_insn("fadd"); unsafe { llvm::LLVMBuildFAdd(self.llbuilder, lhs, rhs, noname()) } } - pub fn fadd_fast(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef { + pub fn fadd_fast(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { self.count_insn("fadd"); unsafe { let instr = llvm::LLVMBuildFAdd(self.llbuilder, lhs, rhs, noname()); @@ -271,35 +267,35 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn sub(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef { + pub fn sub(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { self.count_insn("sub"); unsafe { llvm::LLVMBuildSub(self.llbuilder, lhs, rhs, noname()) } } - pub fn nswsub(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef { + pub fn nswsub(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { self.count_insn("nswsub"); unsafe { llvm::LLVMBuildNSWSub(self.llbuilder, lhs, rhs, noname()) } } - pub fn nuwsub(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef { + pub fn nuwsub(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { self.count_insn("nuwsub"); unsafe { llvm::LLVMBuildNUWSub(self.llbuilder, lhs, rhs, noname()) } } - pub fn fsub(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef { + pub fn fsub(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { self.count_insn("fsub"); unsafe { llvm::LLVMBuildFSub(self.llbuilder, lhs, rhs, noname()) } } - pub fn fsub_fast(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef { + pub fn fsub_fast(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { self.count_insn("fsub"); unsafe { let instr = llvm::LLVMBuildFSub(self.llbuilder, lhs, rhs, noname()); @@ -308,35 +304,35 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn mul(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef { + pub fn mul(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { self.count_insn("mul"); unsafe { llvm::LLVMBuildMul(self.llbuilder, lhs, rhs, noname()) } } - pub fn nswmul(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef { + pub fn nswmul(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { self.count_insn("nswmul"); unsafe { llvm::LLVMBuildNSWMul(self.llbuilder, lhs, rhs, noname()) } } - pub fn nuwmul(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef { + pub fn nuwmul(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { self.count_insn("nuwmul"); unsafe { llvm::LLVMBuildNUWMul(self.llbuilder, lhs, rhs, noname()) } } - pub fn fmul(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef { + pub fn fmul(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { self.count_insn("fmul"); unsafe { llvm::LLVMBuildFMul(self.llbuilder, lhs, rhs, noname()) } } - pub fn fmul_fast(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef { + pub fn fmul_fast(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { self.count_insn("fmul"); unsafe { let instr = llvm::LLVMBuildFMul(self.llbuilder, lhs, rhs, noname()); @@ -346,42 +342,42 @@ impl Builder<'a, 'll, 'tcx> { } - pub fn udiv(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef { + pub fn udiv(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { self.count_insn("udiv"); unsafe { llvm::LLVMBuildUDiv(self.llbuilder, lhs, rhs, noname()) } } - pub fn exactudiv(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef { + pub fn exactudiv(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { self.count_insn("exactudiv"); unsafe { llvm::LLVMBuildExactUDiv(self.llbuilder, lhs, rhs, noname()) } } - pub fn sdiv(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef { + pub fn sdiv(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { self.count_insn("sdiv"); unsafe { llvm::LLVMBuildSDiv(self.llbuilder, lhs, rhs, noname()) } } - pub fn exactsdiv(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef { + pub fn exactsdiv(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { self.count_insn("exactsdiv"); unsafe { llvm::LLVMBuildExactSDiv(self.llbuilder, lhs, rhs, noname()) } } - pub fn fdiv(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef { + pub fn fdiv(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { self.count_insn("fdiv"); unsafe { llvm::LLVMBuildFDiv(self.llbuilder, lhs, rhs, noname()) } } - pub fn fdiv_fast(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef { + pub fn fdiv_fast(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { self.count_insn("fdiv"); unsafe { let instr = llvm::LLVMBuildFDiv(self.llbuilder, lhs, rhs, noname()); @@ -390,28 +386,28 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn urem(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef { + pub fn urem(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { self.count_insn("urem"); unsafe { llvm::LLVMBuildURem(self.llbuilder, lhs, rhs, noname()) } } - pub fn srem(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef { + pub fn srem(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { self.count_insn("srem"); unsafe { llvm::LLVMBuildSRem(self.llbuilder, lhs, rhs, noname()) } } - pub fn frem(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef { + pub fn frem(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { self.count_insn("frem"); unsafe { llvm::LLVMBuildFRem(self.llbuilder, lhs, rhs, noname()) } } - pub fn frem_fast(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef { + pub fn frem_fast(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { self.count_insn("frem"); unsafe { let instr = llvm::LLVMBuildFRem(self.llbuilder, lhs, rhs, noname()); @@ -420,91 +416,91 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn shl(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef { + pub fn shl(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { self.count_insn("shl"); unsafe { llvm::LLVMBuildShl(self.llbuilder, lhs, rhs, noname()) } } - pub fn lshr(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef { + pub fn lshr(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { self.count_insn("lshr"); unsafe { llvm::LLVMBuildLShr(self.llbuilder, lhs, rhs, noname()) } } - pub fn ashr(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef { + pub fn ashr(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { self.count_insn("ashr"); unsafe { llvm::LLVMBuildAShr(self.llbuilder, lhs, rhs, noname()) } } - pub fn and(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef { + pub fn and(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { self.count_insn("and"); unsafe { llvm::LLVMBuildAnd(self.llbuilder, lhs, rhs, noname()) } } - pub fn or(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef { + pub fn or(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { self.count_insn("or"); unsafe { llvm::LLVMBuildOr(self.llbuilder, lhs, rhs, noname()) } } - pub fn xor(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef { + pub fn xor(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { self.count_insn("xor"); unsafe { llvm::LLVMBuildXor(self.llbuilder, lhs, rhs, noname()) } } - pub fn binop(&self, op: Opcode, lhs: ValueRef, rhs: ValueRef) - -> ValueRef { + pub fn binop(&self, op: Opcode, lhs: &'ll Value, rhs: &'ll Value) + -> &'ll Value { self.count_insn("binop"); unsafe { llvm::LLVMBuildBinOp(self.llbuilder, op, lhs, rhs, noname()) } } - pub fn neg(&self, v: ValueRef) -> ValueRef { + pub fn neg(&self, v: &'ll Value) -> &'ll Value { self.count_insn("neg"); unsafe { llvm::LLVMBuildNeg(self.llbuilder, v, noname()) } } - pub fn nswneg(&self, v: ValueRef) -> ValueRef { + pub fn nswneg(&self, v: &'ll Value) -> &'ll Value { self.count_insn("nswneg"); unsafe { llvm::LLVMBuildNSWNeg(self.llbuilder, v, noname()) } } - pub fn nuwneg(&self, v: ValueRef) -> ValueRef { + pub fn nuwneg(&self, v: &'ll Value) -> &'ll Value { self.count_insn("nuwneg"); unsafe { llvm::LLVMBuildNUWNeg(self.llbuilder, v, noname()) } } - pub fn fneg(&self, v: ValueRef) -> ValueRef { + pub fn fneg(&self, v: &'ll Value) -> &'ll Value { self.count_insn("fneg"); unsafe { llvm::LLVMBuildFNeg(self.llbuilder, v, noname()) } } - pub fn not(&self, v: ValueRef) -> ValueRef { + pub fn not(&self, v: &'ll Value) -> &'ll Value { self.count_insn("not"); unsafe { llvm::LLVMBuildNot(self.llbuilder, v, noname()) } } - pub fn alloca(&self, ty: &'ll Type, name: &str, align: Align) -> ValueRef { + pub fn alloca(&self, ty: &'ll Type, name: &str, align: Align) -> &'ll Value { let bx = Builder::with_cx(self.cx); bx.position_at_start(unsafe { llvm::LLVMGetFirstBasicBlock(self.llfn()) @@ -512,7 +508,7 @@ impl Builder<'a, 'll, 'tcx> { bx.dynamic_alloca(ty, name, align) } - pub fn dynamic_alloca(&self, ty: &'ll Type, name: &str, align: Align) -> ValueRef { + pub fn dynamic_alloca(&self, ty: &'ll Type, name: &str, align: Align) -> &'ll Value { self.count_insn("alloca"); unsafe { let alloca = if name.is_empty() { @@ -527,14 +523,14 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn free(&self, ptr: ValueRef) { + pub fn free(&self, ptr: &'ll Value) { self.count_insn("free"); unsafe { llvm::LLVMBuildFree(self.llbuilder, ptr); } } - pub fn load(&self, ptr: ValueRef, align: Align) -> ValueRef { + pub fn load(&self, ptr: &'ll Value, align: Align) -> &'ll Value { self.count_insn("load"); unsafe { let load = llvm::LLVMBuildLoad(self.llbuilder, ptr, noname()); @@ -543,7 +539,7 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn volatile_load(&self, ptr: ValueRef) -> ValueRef { + pub fn volatile_load(&self, ptr: &'ll Value) -> &'ll Value { self.count_insn("load.volatile"); unsafe { let insn = llvm::LLVMBuildLoad(self.llbuilder, ptr, noname()); @@ -552,7 +548,7 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn atomic_load(&self, ptr: ValueRef, order: AtomicOrdering, align: Align) -> ValueRef { + pub fn atomic_load(&self, ptr: &'ll Value, order: AtomicOrdering, align: Align) -> &'ll Value { self.count_insn("load.atomic"); unsafe { let load = llvm::LLVMRustBuildAtomicLoad(self.llbuilder, ptr, noname(), order); @@ -565,7 +561,7 @@ impl Builder<'a, 'll, 'tcx> { } - pub fn range_metadata(&self, load: ValueRef, range: Range) { + pub fn range_metadata(&self, load: &'ll Value, range: Range) { unsafe { let llty = val_ty(load); let v = [ @@ -580,25 +576,25 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn nonnull_metadata(&self, load: ValueRef) { + pub fn nonnull_metadata(&self, load: &'ll Value) { unsafe { llvm::LLVMSetMetadata(load, llvm::MD_nonnull as c_uint, llvm::LLVMMDNodeInContext(self.cx.llcx, ptr::null(), 0)); } } - pub fn store(&self, val: ValueRef, ptr: ValueRef, align: Align) -> ValueRef { + pub fn store(&self, val: &'ll Value, ptr: &'ll Value, align: Align) -> &'ll Value { self.store_with_flags(val, ptr, align, MemFlags::empty()) } pub fn store_with_flags( &self, - val: ValueRef, - ptr: ValueRef, + val: &'ll Value, + ptr: &'ll Value, align: Align, flags: MemFlags, - ) -> ValueRef { - debug!("Store {:?} -> {:?} ({:?})", Value(val), Value(ptr), flags); + ) -> &'ll Value { + debug!("Store {:?} -> {:?} ({:?})", val, ptr, flags); self.count_insn("store"); let ptr = self.check_store(val, ptr); unsafe { @@ -625,9 +621,9 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn atomic_store(&self, val: ValueRef, ptr: ValueRef, + pub fn atomic_store(&self, val: &'ll Value, ptr: &'ll Value, order: AtomicOrdering, align: Align) { - debug!("Store {:?} -> {:?}", Value(val), Value(ptr)); + debug!("Store {:?} -> {:?}", val, ptr); self.count_insn("store.atomic"); let ptr = self.check_store(val, ptr); unsafe { @@ -638,7 +634,7 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn gep(&self, ptr: ValueRef, indices: &[ValueRef]) -> ValueRef { + pub fn gep(&self, ptr: &'ll Value, indices: &[&'ll Value]) -> &'ll Value { self.count_insn("gep"); unsafe { llvm::LLVMBuildGEP(self.llbuilder, ptr, indices.as_ptr(), @@ -646,7 +642,7 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn inbounds_gep(&self, ptr: ValueRef, indices: &[ValueRef]) -> ValueRef { + pub fn inbounds_gep(&self, ptr: &'ll Value, indices: &[&'ll Value]) -> &'ll Value { self.count_insn("inboundsgep"); unsafe { llvm::LLVMBuildInBoundsGEP( @@ -654,7 +650,7 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn struct_gep(&self, ptr: ValueRef, idx: u64) -> ValueRef { + pub fn struct_gep(&self, ptr: &'ll Value, idx: u64) -> &'ll Value { self.count_insn("structgep"); assert_eq!(idx as c_uint as u64, idx); unsafe { @@ -662,14 +658,14 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn global_string(&self, _str: *const c_char) -> ValueRef { + pub fn global_string(&self, _str: *const c_char) -> &'ll Value { self.count_insn("globalstring"); unsafe { llvm::LLVMBuildGlobalString(self.llbuilder, _str, noname()) } } - pub fn global_string_ptr(&self, _str: *const c_char) -> ValueRef { + pub fn global_string_ptr(&self, _str: *const c_char) -> &'ll Value { self.count_insn("globalstringptr"); unsafe { llvm::LLVMBuildGlobalStringPtr(self.llbuilder, _str, noname()) @@ -677,133 +673,133 @@ impl Builder<'a, 'll, 'tcx> { } /* Casts */ - pub fn trunc(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef { + pub fn trunc(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { self.count_insn("trunc"); unsafe { llvm::LLVMBuildTrunc(self.llbuilder, val, dest_ty, noname()) } } - pub fn zext(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef { + pub fn zext(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { self.count_insn("zext"); unsafe { llvm::LLVMBuildZExt(self.llbuilder, val, dest_ty, noname()) } } - pub fn sext(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef { + pub fn sext(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { self.count_insn("sext"); unsafe { llvm::LLVMBuildSExt(self.llbuilder, val, dest_ty, noname()) } } - pub fn fptoui(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef { + pub fn fptoui(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { self.count_insn("fptoui"); unsafe { llvm::LLVMBuildFPToUI(self.llbuilder, val, dest_ty, noname()) } } - pub fn fptosi(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef { + pub fn fptosi(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { self.count_insn("fptosi"); unsafe { llvm::LLVMBuildFPToSI(self.llbuilder, val, dest_ty,noname()) } } - pub fn uitofp(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef { + pub fn uitofp(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { self.count_insn("uitofp"); unsafe { llvm::LLVMBuildUIToFP(self.llbuilder, val, dest_ty, noname()) } } - pub fn sitofp(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef { + pub fn sitofp(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { self.count_insn("sitofp"); unsafe { llvm::LLVMBuildSIToFP(self.llbuilder, val, dest_ty, noname()) } } - pub fn fptrunc(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef { + pub fn fptrunc(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { self.count_insn("fptrunc"); unsafe { llvm::LLVMBuildFPTrunc(self.llbuilder, val, dest_ty, noname()) } } - pub fn fpext(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef { + pub fn fpext(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { self.count_insn("fpext"); unsafe { llvm::LLVMBuildFPExt(self.llbuilder, val, dest_ty, noname()) } } - pub fn ptrtoint(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef { + pub fn ptrtoint(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { self.count_insn("ptrtoint"); unsafe { llvm::LLVMBuildPtrToInt(self.llbuilder, val, dest_ty, noname()) } } - pub fn inttoptr(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef { + pub fn inttoptr(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { self.count_insn("inttoptr"); unsafe { llvm::LLVMBuildIntToPtr(self.llbuilder, val, dest_ty, noname()) } } - pub fn bitcast(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef { + pub fn bitcast(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { self.count_insn("bitcast"); unsafe { llvm::LLVMBuildBitCast(self.llbuilder, val, dest_ty, noname()) } } - pub fn zext_or_bitcast(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef { + pub fn zext_or_bitcast(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { self.count_insn("zextorbitcast"); unsafe { llvm::LLVMBuildZExtOrBitCast(self.llbuilder, val, dest_ty, noname()) } } - pub fn sext_or_bitcast(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef { + pub fn sext_or_bitcast(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { self.count_insn("sextorbitcast"); unsafe { llvm::LLVMBuildSExtOrBitCast(self.llbuilder, val, dest_ty, noname()) } } - pub fn trunc_or_bitcast(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef { + pub fn trunc_or_bitcast(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { self.count_insn("truncorbitcast"); unsafe { llvm::LLVMBuildTruncOrBitCast(self.llbuilder, val, dest_ty, noname()) } } - pub fn cast(&self, op: Opcode, val: ValueRef, dest_ty: &'ll Type) -> ValueRef { + pub fn cast(&self, op: Opcode, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { self.count_insn("cast"); unsafe { llvm::LLVMBuildCast(self.llbuilder, op, val, dest_ty, noname()) } } - pub fn pointercast(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef { + pub fn pointercast(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { self.count_insn("pointercast"); unsafe { llvm::LLVMBuildPointerCast(self.llbuilder, val, dest_ty, noname()) } } - pub fn intcast(&self, val: ValueRef, dest_ty: &'ll Type, is_signed: bool) -> ValueRef { + pub fn intcast(&self, val: &'ll Value, dest_ty: &'ll Type, is_signed: bool) -> &'ll Value { self.count_insn("intcast"); unsafe { llvm::LLVMRustBuildIntCast(self.llbuilder, val, dest_ty, is_signed) } } - pub fn fpcast(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef { + pub fn fpcast(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { self.count_insn("fpcast"); unsafe { llvm::LLVMBuildFPCast(self.llbuilder, val, dest_ty, noname()) @@ -812,14 +808,14 @@ impl Builder<'a, 'll, 'tcx> { /* Comparisons */ - pub fn icmp(&self, op: IntPredicate, lhs: ValueRef, rhs: ValueRef) -> ValueRef { + pub fn icmp(&self, op: IntPredicate, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { self.count_insn("icmp"); unsafe { llvm::LLVMBuildICmp(self.llbuilder, op as c_uint, lhs, rhs, noname()) } } - pub fn fcmp(&self, op: RealPredicate, lhs: ValueRef, rhs: ValueRef) -> ValueRef { + pub fn fcmp(&self, op: RealPredicate, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { self.count_insn("fcmp"); unsafe { llvm::LLVMBuildFCmp(self.llbuilder, op as c_uint, lhs, rhs, noname()) @@ -827,14 +823,14 @@ impl Builder<'a, 'll, 'tcx> { } /* Miscellaneous instructions */ - pub fn empty_phi(&self, ty: &'ll Type) -> ValueRef { + pub fn empty_phi(&self, ty: &'ll Type) -> &'ll Value { self.count_insn("emptyphi"); unsafe { llvm::LLVMBuildPhi(self.llbuilder, ty, noname()) } } - pub fn phi(&self, ty: &'ll Type, vals: &[ValueRef], bbs: &[BasicBlockRef]) -> ValueRef { + pub fn phi(&self, ty: &'ll Type, vals: &[&'ll Value], bbs: &[BasicBlockRef]) -> &'ll Value { assert_eq!(vals.len(), bbs.len()); let phi = self.empty_phi(ty); self.count_insn("addincoming"); @@ -873,9 +869,9 @@ impl Builder<'a, 'll, 'tcx> { } pub fn inline_asm_call(&self, asm: *const c_char, cons: *const c_char, - inputs: &[ValueRef], output: &'ll Type, + inputs: &[&'ll Value], output: &'ll Type, volatile: bool, alignstack: bool, - dia: AsmDialect) -> ValueRef { + dia: AsmDialect) -> &'ll Value { self.count_insn("inlineasm"); let volatile = if volatile { llvm::True } @@ -884,7 +880,7 @@ impl Builder<'a, 'll, 'tcx> { else { llvm::False }; let argtys = inputs.iter().map(|v| { - debug!("Asm Input Type: {:?}", Value(*v)); + debug!("Asm Input Type: {:?}", *v); val_ty(*v) }).collect::>(); @@ -897,16 +893,13 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn call(&self, llfn: ValueRef, args: &[ValueRef], - bundle: Option<&OperandBundleDef>) -> ValueRef { + pub fn call(&self, llfn: &'ll Value, args: &[&'ll Value], + bundle: Option<&OperandBundleDef>) -> &'ll Value { self.count_insn("call"); - debug!("Call {:?} with args ({})", - Value(llfn), - args.iter() - .map(|&v| format!("{:?}", Value(v))) - .collect::>() - .join(", ")); + debug!("Call {:?} with args ({:?})", + llfn, + args); let args = self.check_call("call", llfn, args); let bundle = bundle.as_ref().and_then(|b| NonNull::new(b.raw())); @@ -917,63 +910,65 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn minnum(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef { + pub fn minnum(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { self.count_insn("minnum"); unsafe { let instr = llvm::LLVMRustBuildMinNum(self.llbuilder, lhs, rhs); - if instr.is_null() { - bug!("LLVMRustBuildMinNum is not available in LLVM version < 6.0"); - } - instr + instr.expect("LLVMRustBuildMinNum is not available in LLVM version < 6.0") } } - pub fn maxnum(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef { + pub fn maxnum(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { self.count_insn("maxnum"); unsafe { let instr = llvm::LLVMRustBuildMaxNum(self.llbuilder, lhs, rhs); - if instr.is_null() { - bug!("LLVMRustBuildMaxNum is not available in LLVM version < 6.0"); - } - instr + instr.expect("LLVMRustBuildMaxNum is not available in LLVM version < 6.0") } } - pub fn select(&self, cond: ValueRef, then_val: ValueRef, else_val: ValueRef) -> ValueRef { + pub fn select( + &self, cond: &'ll Value, + then_val: &'ll Value, + else_val: &'ll Value, + ) -> &'ll Value { self.count_insn("select"); unsafe { llvm::LLVMBuildSelect(self.llbuilder, cond, then_val, else_val, noname()) } } - pub fn va_arg(&self, list: ValueRef, ty: &'ll Type) -> ValueRef { + pub fn va_arg(&self, list: &'ll Value, ty: &'ll Type) -> &'ll Value { self.count_insn("vaarg"); unsafe { llvm::LLVMBuildVAArg(self.llbuilder, list, ty, noname()) } } - pub fn extract_element(&self, vec: ValueRef, idx: ValueRef) -> ValueRef { + pub fn extract_element(&self, vec: &'ll Value, idx: &'ll Value) -> &'ll Value { self.count_insn("extractelement"); unsafe { llvm::LLVMBuildExtractElement(self.llbuilder, vec, idx, noname()) } } - pub fn insert_element(&self, vec: ValueRef, elt: ValueRef, idx: ValueRef) -> ValueRef { + pub fn insert_element( + &self, vec: &'ll Value, + elt: &'ll Value, + idx: &'ll Value, + ) -> &'ll Value { self.count_insn("insertelement"); unsafe { llvm::LLVMBuildInsertElement(self.llbuilder, vec, elt, idx, noname()) } } - pub fn shuffle_vector(&self, v1: ValueRef, v2: ValueRef, mask: ValueRef) -> ValueRef { + pub fn shuffle_vector(&self, v1: &'ll Value, v2: &'ll Value, mask: &'ll Value) -> &'ll Value { self.count_insn("shufflevector"); unsafe { llvm::LLVMBuildShuffleVector(self.llbuilder, v1, v2, mask, noname()) } } - pub fn vector_splat(&self, num_elts: usize, elt: ValueRef) -> ValueRef { + pub fn vector_splat(&self, num_elts: usize, elt: &'ll Value) -> &'ll Value { unsafe { let elt_ty = val_ty(elt); let undef = llvm::LLVMGetUndef(Type::vector(elt_ty, num_elts as u64)); @@ -983,148 +978,113 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn vector_reduce_fadd_fast(&self, acc: ValueRef, src: ValueRef) -> ValueRef { + pub fn vector_reduce_fadd_fast(&self, acc: &'ll Value, src: &'ll Value) -> &'ll Value { self.count_insn("vector.reduce.fadd_fast"); unsafe { // FIXME: add a non-fast math version once // https://bugs.llvm.org/show_bug.cgi?id=36732 // is fixed. let instr = llvm::LLVMRustBuildVectorReduceFAdd(self.llbuilder, acc, src); - if instr.is_null() { - bug!("LLVMRustBuildVectorReduceFAdd is not available in LLVM version < 5.0"); - } + let instr = instr.expect("LLVMRustBuildVectorReduceFAdd is not available in LLVM version < 5.0"); llvm::LLVMRustSetHasUnsafeAlgebra(instr); instr } } - pub fn vector_reduce_fmul_fast(&self, acc: ValueRef, src: ValueRef) -> ValueRef { + pub fn vector_reduce_fmul_fast(&self, acc: &'ll Value, src: &'ll Value) -> &'ll Value { self.count_insn("vector.reduce.fmul_fast"); unsafe { // FIXME: add a non-fast math version once // https://bugs.llvm.org/show_bug.cgi?id=36732 // is fixed. let instr = llvm::LLVMRustBuildVectorReduceFMul(self.llbuilder, acc, src); - if instr.is_null() { - bug!("LLVMRustBuildVectorReduceFMul is not available in LLVM version < 5.0"); - } + let instr = instr.expect("LLVMRustBuildVectorReduceFMul is not available in LLVM version < 5.0"); llvm::LLVMRustSetHasUnsafeAlgebra(instr); instr } } - pub fn vector_reduce_add(&self, src: ValueRef) -> ValueRef { + pub fn vector_reduce_add(&self, src: &'ll Value) -> &'ll Value { self.count_insn("vector.reduce.add"); unsafe { let instr = llvm::LLVMRustBuildVectorReduceAdd(self.llbuilder, src); - if instr.is_null() { - bug!("LLVMRustBuildVectorReduceAdd is not available in LLVM version < 5.0"); - } - instr + instr.expect("LLVMRustBuildVectorReduceAdd is not available in LLVM version < 5.0") } } - pub fn vector_reduce_mul(&self, src: ValueRef) -> ValueRef { + pub fn vector_reduce_mul(&self, src: &'ll Value) -> &'ll Value { self.count_insn("vector.reduce.mul"); unsafe { let instr = llvm::LLVMRustBuildVectorReduceMul(self.llbuilder, src); - if instr.is_null() { - bug!("LLVMRustBuildVectorReduceMul is not available in LLVM version < 5.0"); - } - instr + instr.expect("LLVMRustBuildVectorReduceMul is not available in LLVM version < 5.0") } } - pub fn vector_reduce_and(&self, src: ValueRef) -> ValueRef { + pub fn vector_reduce_and(&self, src: &'ll Value) -> &'ll Value { self.count_insn("vector.reduce.and"); unsafe { let instr = llvm::LLVMRustBuildVectorReduceAnd(self.llbuilder, src); - if instr.is_null() { - bug!("LLVMRustBuildVectorReduceAnd is not available in LLVM version < 5.0"); - } - instr + instr.expect("LLVMRustBuildVectorReduceAnd is not available in LLVM version < 5.0") } } - pub fn vector_reduce_or(&self, src: ValueRef) -> ValueRef { + pub fn vector_reduce_or(&self, src: &'ll Value) -> &'ll Value { self.count_insn("vector.reduce.or"); unsafe { let instr = llvm::LLVMRustBuildVectorReduceOr(self.llbuilder, src); - if instr.is_null() { - bug!("LLVMRustBuildVectorReduceOr is not available in LLVM version < 5.0"); - } - instr + instr.expect("LLVMRustBuildVectorReduceOr is not available in LLVM version < 5.0") } } - pub fn vector_reduce_xor(&self, src: ValueRef) -> ValueRef { + pub fn vector_reduce_xor(&self, src: &'ll Value) -> &'ll Value { self.count_insn("vector.reduce.xor"); unsafe { let instr = llvm::LLVMRustBuildVectorReduceXor(self.llbuilder, src); - if instr.is_null() { - bug!("LLVMRustBuildVectorReduceXor is not available in LLVM version < 5.0"); - } - instr + instr.expect("LLVMRustBuildVectorReduceXor is not available in LLVM version < 5.0") } } - pub fn vector_reduce_fmin(&self, src: ValueRef) -> ValueRef { + pub fn vector_reduce_fmin(&self, src: &'ll Value) -> &'ll Value { self.count_insn("vector.reduce.fmin"); unsafe { let instr = llvm::LLVMRustBuildVectorReduceFMin(self.llbuilder, src, /*NoNaNs:*/ false); - if instr.is_null() { - bug!("LLVMRustBuildVectorReduceFMin is not available in LLVM version < 5.0"); - } - instr + instr.expect("LLVMRustBuildVectorReduceFMin is not available in LLVM version < 5.0") } } - pub fn vector_reduce_fmax(&self, src: ValueRef) -> ValueRef { + pub fn vector_reduce_fmax(&self, src: &'ll Value) -> &'ll Value { self.count_insn("vector.reduce.fmax"); unsafe { let instr = llvm::LLVMRustBuildVectorReduceFMax(self.llbuilder, src, /*NoNaNs:*/ false); - if instr.is_null() { - bug!("LLVMRustBuildVectorReduceFMax is not available in LLVM version < 5.0"); - } - instr + instr.expect("LLVMRustBuildVectorReduceFMax is not available in LLVM version < 5.0") } } - pub fn vector_reduce_fmin_fast(&self, src: ValueRef) -> ValueRef { + pub fn vector_reduce_fmin_fast(&self, src: &'ll Value) -> &'ll Value { self.count_insn("vector.reduce.fmin_fast"); unsafe { let instr = llvm::LLVMRustBuildVectorReduceFMin(self.llbuilder, src, /*NoNaNs:*/ true); - if instr.is_null() { - bug!("LLVMRustBuildVectorReduceFMin is not available in LLVM version < 5.0"); - } + let instr = instr.expect("LLVMRustBuildVectorReduceFMin is not available in LLVM version < 5.0"); llvm::LLVMRustSetHasUnsafeAlgebra(instr); instr } } - pub fn vector_reduce_fmax_fast(&self, src: ValueRef) -> ValueRef { + pub fn vector_reduce_fmax_fast(&self, src: &'ll Value) -> &'ll Value { self.count_insn("vector.reduce.fmax_fast"); unsafe { let instr = llvm::LLVMRustBuildVectorReduceFMax(self.llbuilder, src, /*NoNaNs:*/ true); - if instr.is_null() { - bug!("LLVMRustBuildVectorReduceFMax is not available in LLVM version < 5.0"); - } + let instr = instr.expect("LLVMRustBuildVectorReduceFMax is not available in LLVM version < 5.0"); llvm::LLVMRustSetHasUnsafeAlgebra(instr); instr } } - pub fn vector_reduce_min(&self, src: ValueRef, is_signed: bool) -> ValueRef { + pub fn vector_reduce_min(&self, src: &'ll Value, is_signed: bool) -> &'ll Value { self.count_insn("vector.reduce.min"); unsafe { let instr = llvm::LLVMRustBuildVectorReduceMin(self.llbuilder, src, is_signed); - if instr.is_null() { - bug!("LLVMRustBuildVectorReduceMin is not available in LLVM version < 5.0"); - } - instr + instr.expect("LLVMRustBuildVectorReduceMin is not available in LLVM version < 5.0") } } - pub fn vector_reduce_max(&self, src: ValueRef, is_signed: bool) -> ValueRef { + pub fn vector_reduce_max(&self, src: &'ll Value, is_signed: bool) -> &'ll Value { self.count_insn("vector.reduce.max"); unsafe { let instr = llvm::LLVMRustBuildVectorReduceMax(self.llbuilder, src, is_signed); - if instr.is_null() { - bug!("LLVMRustBuildVectorReduceMax is not available in LLVM version < 5.0"); - } - instr + instr.expect("LLVMRustBuildVectorReduceMax is not available in LLVM version < 5.0") } } - pub fn extract_value(&self, agg_val: ValueRef, idx: u64) -> ValueRef { + pub fn extract_value(&self, agg_val: &'ll Value, idx: u64) -> &'ll Value { self.count_insn("extractvalue"); assert_eq!(idx as c_uint as u64, idx); unsafe { @@ -1132,8 +1092,8 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn insert_value(&self, agg_val: ValueRef, elt: ValueRef, - idx: u64) -> ValueRef { + pub fn insert_value(&self, agg_val: &'ll Value, elt: &'ll Value, + idx: u64) -> &'ll Value { self.count_insn("insertvalue"); assert_eq!(idx as c_uint as u64, idx); unsafe { @@ -1142,29 +1102,29 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn is_null(&self, val: ValueRef) -> ValueRef { + pub fn is_null(&self, val: &'ll Value) -> &'ll Value { self.count_insn("isnull"); unsafe { llvm::LLVMBuildIsNull(self.llbuilder, val, noname()) } } - pub fn is_not_null(&self, val: ValueRef) -> ValueRef { + pub fn is_not_null(&self, val: &'ll Value) -> &'ll Value { self.count_insn("isnotnull"); unsafe { llvm::LLVMBuildIsNotNull(self.llbuilder, val, noname()) } } - pub fn ptrdiff(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef { + pub fn ptrdiff(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { self.count_insn("ptrdiff"); unsafe { llvm::LLVMBuildPtrDiff(self.llbuilder, lhs, rhs, noname()) } } - pub fn landing_pad(&self, ty: &'ll Type, pers_fn: ValueRef, - num_clauses: usize) -> ValueRef { + pub fn landing_pad(&self, ty: &'ll Type, pers_fn: &'ll Value, + num_clauses: usize) -> &'ll Value { self.count_insn("landingpad"); unsafe { llvm::LLVMBuildLandingPad(self.llbuilder, ty, pers_fn, @@ -1172,20 +1132,20 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn add_clause(&self, landing_pad: ValueRef, clause: ValueRef) { + pub fn add_clause(&self, landing_pad: &'ll Value, clause: &'ll Value) { unsafe { llvm::LLVMAddClause(landing_pad, clause); } } - pub fn set_cleanup(&self, landing_pad: ValueRef) { + pub fn set_cleanup(&self, landing_pad: &'ll Value) { self.count_insn("setcleanup"); unsafe { llvm::LLVMSetCleanup(landing_pad, llvm::True); } } - pub fn resume(&self, exn: ValueRef) -> ValueRef { + pub fn resume(&self, exn: &'ll Value) -> &'ll Value { self.count_insn("resume"); unsafe { llvm::LLVMBuildResume(self.llbuilder, exn) @@ -1193,10 +1153,9 @@ impl Builder<'a, 'll, 'tcx> { } pub fn cleanup_pad(&self, - parent: Option, - args: &[ValueRef]) -> ValueRef { + parent: Option<&'ll Value>, + args: &[&'ll Value]) -> &'ll Value { self.count_insn("cleanuppad"); - let parent = parent.and_then(NonNull::new); let name = CString::new("cleanuppad").unwrap(); let ret = unsafe { llvm::LLVMRustBuildCleanupPad(self.llbuilder, @@ -1205,24 +1164,22 @@ impl Builder<'a, 'll, 'tcx> { args.as_ptr(), name.as_ptr()) }; - assert!(!ret.is_null(), "LLVM does not have support for cleanuppad"); - return ret + ret.expect("LLVM does not have support for cleanuppad") } - pub fn cleanup_ret(&self, cleanup: ValueRef, - unwind: Option) -> ValueRef { + pub fn cleanup_ret(&self, cleanup: &'ll Value, + unwind: Option) -> &'ll Value { self.count_insn("cleanupret"); let unwind = unwind.and_then(NonNull::new); let ret = unsafe { llvm::LLVMRustBuildCleanupRet(self.llbuilder, cleanup, unwind) }; - assert!(!ret.is_null(), "LLVM does not have support for cleanupret"); - return ret + ret.expect("LLVM does not have support for cleanupret") } pub fn catch_pad(&self, - parent: ValueRef, - args: &[ValueRef]) -> ValueRef { + parent: &'ll Value, + args: &[&'ll Value]) -> &'ll Value { self.count_insn("catchpad"); let name = CString::new("catchpad").unwrap(); let ret = unsafe { @@ -1230,25 +1187,24 @@ impl Builder<'a, 'll, 'tcx> { args.len() as c_uint, args.as_ptr(), name.as_ptr()) }; - assert!(!ret.is_null(), "LLVM does not have support for catchpad"); - return ret + ret.expect("LLVM does not have support for catchpad") } - pub fn catch_ret(&self, pad: ValueRef, unwind: BasicBlockRef) -> ValueRef { + pub fn catch_ret(&self, pad: &'ll Value, unwind: BasicBlockRef) -> &'ll Value { self.count_insn("catchret"); let ret = unsafe { llvm::LLVMRustBuildCatchRet(self.llbuilder, pad, unwind) }; - assert!(!ret.is_null(), "LLVM does not have support for catchret"); - return ret + ret.expect("LLVM does not have support for catchret") } - pub fn catch_switch(&self, - parent: Option, - unwind: Option, - num_handlers: usize) -> ValueRef { + pub fn catch_switch( + &self, + parent: Option<&'ll Value>, + unwind: Option, + num_handlers: usize, + ) -> &'ll Value { self.count_insn("catchswitch"); - let parent = parent.and_then(NonNull::new); let unwind = unwind.and_then(NonNull::new); let name = CString::new("catchswitch").unwrap(); let ret = unsafe { @@ -1256,36 +1212,43 @@ impl Builder<'a, 'll, 'tcx> { num_handlers as c_uint, name.as_ptr()) }; - assert!(!ret.is_null(), "LLVM does not have support for catchswitch"); - return ret + ret.expect("LLVM does not have support for catchswitch") } - pub fn add_handler(&self, catch_switch: ValueRef, handler: BasicBlockRef) { + pub fn add_handler(&self, catch_switch: &'ll Value, handler: BasicBlockRef) { unsafe { llvm::LLVMRustAddHandler(catch_switch, handler); } } - pub fn set_personality_fn(&self, personality: ValueRef) { + pub fn set_personality_fn(&self, personality: &'ll Value) { unsafe { llvm::LLVMSetPersonalityFn(self.llfn(), personality); } } // Atomic Operations - pub fn atomic_cmpxchg(&self, dst: ValueRef, - cmp: ValueRef, src: ValueRef, - order: AtomicOrdering, - failure_order: AtomicOrdering, - weak: llvm::Bool) -> ValueRef { + pub fn atomic_cmpxchg( + &self, + dst: &'ll Value, + cmp: &'ll Value, + src: &'ll Value, + order: AtomicOrdering, + failure_order: AtomicOrdering, + weak: llvm::Bool, + ) -> &'ll Value { unsafe { llvm::LLVMRustBuildAtomicCmpXchg(self.llbuilder, dst, cmp, src, order, failure_order, weak) } } - pub fn atomic_rmw(&self, op: AtomicRmwBinOp, - dst: ValueRef, src: ValueRef, - order: AtomicOrdering) -> ValueRef { + pub fn atomic_rmw( + &self, + op: AtomicRmwBinOp, + dst: &'ll Value, + src: &'ll Value, + order: AtomicOrdering, + ) -> &'ll Value { unsafe { llvm::LLVMBuildAtomicRMW(self.llbuilder, op, dst, src, order, False) } @@ -1297,20 +1260,20 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn add_case(&self, s: ValueRef, on_val: ValueRef, dest: BasicBlockRef) { + pub fn add_case(&self, s: &'ll Value, on_val: &'ll Value, dest: BasicBlockRef) { unsafe { llvm::LLVMAddCase(s, on_val, dest) } } - pub fn add_incoming_to_phi(&self, phi: ValueRef, val: ValueRef, bb: BasicBlockRef) { + pub fn add_incoming_to_phi(&self, phi: &'ll Value, val: &'ll Value, bb: BasicBlockRef) { self.count_insn("addincoming"); unsafe { llvm::LLVMAddIncoming(phi, &val, &bb, 1 as c_uint); } } - pub fn set_invariant_load(&self, load: ValueRef) { + pub fn set_invariant_load(&self, load: &'ll Value) { unsafe { llvm::LLVMSetMetadata(load, llvm::MD_invariant_load as c_uint, llvm::LLVMMDNodeInContext(self.cx.llcx, ptr::null(), 0)); @@ -1319,8 +1282,8 @@ impl Builder<'a, 'll, 'tcx> { /// Returns the ptr value that should be used for storing `val`. fn check_store<'b>(&self, - val: ValueRef, - ptr: ValueRef) -> ValueRef { + val: &'ll Value, + ptr: &'ll Value) -> &'ll Value { let dest_ptr_ty = val_ty(ptr); let stored_ty = val_ty(val); let stored_ptr_ty = stored_ty.ptr_to(); @@ -1340,8 +1303,8 @@ impl Builder<'a, 'll, 'tcx> { /// Returns the args that should be used for a call to `llfn`. fn check_call<'b>(&self, typ: &str, - llfn: ValueRef, - args: &'b [ValueRef]) -> Cow<'b, [ValueRef]> { + llfn: &'ll Value, + args: &'b [&'ll Value]) -> Cow<'b, [&'ll Value]> { let mut fn_ty = val_ty(llfn); // Strip off pointers while fn_ty.kind() == llvm::TypeKind::Pointer { @@ -1369,8 +1332,7 @@ impl Builder<'a, 'll, 'tcx> { if expected_ty != actual_ty { debug!("Type mismatch in function call of {:?}. \ Expected {:?} for param {}, got {:?}; injecting bitcast", - Value(llfn), - expected_ty, i, actual_ty); + llfn, expected_ty, i, actual_ty); self.bitcast(actual_val, expected_ty) } else { actual_val @@ -1381,11 +1343,11 @@ impl Builder<'a, 'll, 'tcx> { return Cow::Owned(casted_args); } - pub fn lifetime_start(&self, ptr: ValueRef, size: Size) { + pub fn lifetime_start(&self, ptr: &'ll Value, size: Size) { self.call_lifetime_intrinsic("llvm.lifetime.start", ptr, size); } - pub fn lifetime_end(&self, ptr: ValueRef, size: Size) { + pub fn lifetime_end(&self, ptr: &'ll Value, size: Size) { self.call_lifetime_intrinsic("llvm.lifetime.end", ptr, size); } @@ -1397,7 +1359,7 @@ impl Builder<'a, 'll, 'tcx> { /// /// If LLVM lifetime intrinsic support is disabled (i.e. optimizations /// off) or `ptr` is zero-sized, then no-op (does not call `emit`). - fn call_lifetime_intrinsic(&self, intrinsic: &str, ptr: ValueRef, size: Size) { + fn call_lifetime_intrinsic(&self, intrinsic: &str, ptr: &'ll Value, size: Size) { if self.cx.sess().opts.optimize == config::OptLevel::No { return; } diff --git a/src/librustc_codegen_llvm/callee.rs b/src/librustc_codegen_llvm/callee.rs index 2c01bd42cc77a..e64dedac55a24 100644 --- a/src/librustc_codegen_llvm/callee.rs +++ b/src/librustc_codegen_llvm/callee.rs @@ -18,9 +18,10 @@ use attributes; use common::{self, CodegenCx}; use consts; use declare; -use llvm::{self, ValueRef}; +use llvm; use monomorphize::Instance; use type_of::LayoutLlvmExt; +use value::Value; use rustc::hir::def_id::DefId; use rustc::ty::{self, TypeFoldable}; @@ -34,10 +35,10 @@ use rustc::ty::subst::Substs; /// /// - `cx`: the crate context /// - `instance`: the instance to be instantiated -pub fn get_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, - instance: Instance<'tcx>) - -> ValueRef -{ +pub fn get_fn( + cx: &CodegenCx<'ll, 'tcx>, + instance: Instance<'tcx>, +) -> &'ll Value { let tcx = cx.tcx; debug!("get_fn(instance={:?})", instance); @@ -204,11 +205,11 @@ pub fn get_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, llfn } -pub fn resolve_and_get_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, - def_id: DefId, - substs: &'tcx Substs<'tcx>) - -> ValueRef -{ +pub fn resolve_and_get_fn( + cx: &CodegenCx<'ll, 'tcx>, + def_id: DefId, + substs: &'tcx Substs<'tcx>, +) -> &'ll Value { get_fn( cx, ty::Instance::resolve( diff --git a/src/librustc_codegen_llvm/common.rs b/src/librustc_codegen_llvm/common.rs index 7b90616416890..90e42dd803aad 100644 --- a/src/librustc_codegen_llvm/common.rs +++ b/src/librustc_codegen_llvm/common.rs @@ -12,8 +12,7 @@ //! Code that is useful in various codegen modules. -use llvm; -use llvm::{ValueRef, TypeKind}; +use llvm::{self, TypeKind}; use llvm::{True, False, Bool, OperandBundleDef}; use rustc::hir::def_id::DefId; use rustc::middle::lang_items::LangItem; @@ -25,6 +24,7 @@ use declare; use type_::Type; use type_of::LayoutLlvmExt; use value::Value; + use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::layout::{HasDataLayout, LayoutOf}; use rustc::hir; @@ -90,20 +90,20 @@ pub fn type_is_freeze<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> bo /// When inside of a landing pad, each function call in LLVM IR needs to be /// annotated with which landing pad it's a part of. This is accomplished via /// the `OperandBundleDef` value created for MSVC landing pads. -pub struct Funclet { - cleanuppad: ValueRef, +pub struct Funclet<'ll> { + cleanuppad: &'ll Value, operand: OperandBundleDef, } -impl Funclet { - pub fn new(cleanuppad: ValueRef) -> Funclet { +impl Funclet<'ll> { + pub fn new(cleanuppad: &'ll Value) -> Self { Funclet { cleanuppad, operand: OperandBundleDef::new("funclet", &[cleanuppad]), } } - pub fn cleanuppad(&self) -> ValueRef { + pub fn cleanuppad(&self) -> &'ll Value { self.cleanuppad } @@ -112,62 +112,61 @@ impl Funclet { } } -// TODO: use proper lifetime in return type -pub fn val_ty(v: ValueRef) -> &'static Type { +pub fn val_ty(v: &'ll Value) -> &'ll Type { unsafe { - llvm::LLVMTypeOf(&*v) + llvm::LLVMTypeOf(v) } } // LLVM constant constructors. -pub fn C_null(t: &Type) -> ValueRef { +pub fn C_null(t: &'ll Type) -> &'ll Value { unsafe { llvm::LLVMConstNull(t) } } -pub fn C_undef(t: &Type) -> ValueRef { +pub fn C_undef(t: &'ll Type) -> &'ll Value { unsafe { llvm::LLVMGetUndef(t) } } -pub fn C_int(t: &Type, i: i64) -> ValueRef { +pub fn C_int(t: &'ll Type, i: i64) -> &'ll Value { unsafe { llvm::LLVMConstInt(t, i as u64, True) } } -pub fn C_uint(t: &Type, i: u64) -> ValueRef { +pub fn C_uint(t: &'ll Type, i: u64) -> &'ll Value { unsafe { llvm::LLVMConstInt(t, i, False) } } -pub fn C_uint_big(t: &Type, u: u128) -> ValueRef { +pub fn C_uint_big(t: &'ll Type, u: u128) -> &'ll Value { unsafe { let words = [u as u64, (u >> 64) as u64]; llvm::LLVMConstIntOfArbitraryPrecision(t, 2, words.as_ptr()) } } -pub fn C_bool(cx: &CodegenCx, val: bool) -> ValueRef { +pub fn C_bool(cx: &CodegenCx<'ll, '_>, val: bool) -> &'ll Value { C_uint(Type::i1(cx), val as u64) } -pub fn C_i32(cx: &CodegenCx, i: i32) -> ValueRef { +pub fn C_i32(cx: &CodegenCx<'ll, '_>, i: i32) -> &'ll Value { C_int(Type::i32(cx), i as i64) } -pub fn C_u32(cx: &CodegenCx, i: u32) -> ValueRef { +pub fn C_u32(cx: &CodegenCx<'ll, '_>, i: u32) -> &'ll Value { C_uint(Type::i32(cx), i as u64) } -pub fn C_u64(cx: &CodegenCx, i: u64) -> ValueRef { +pub fn C_u64(cx: &CodegenCx<'ll, '_>, i: u64) -> &'ll Value { C_uint(Type::i64(cx), i) } -pub fn C_usize(cx: &CodegenCx, i: u64) -> ValueRef { +pub fn C_usize(cx: &CodegenCx<'ll, '_>, i: u64) -> &'ll Value { let bit_size = cx.data_layout().pointer_size.bits(); if bit_size < 64 { // make sure it doesn't overflow @@ -177,14 +176,14 @@ pub fn C_usize(cx: &CodegenCx, i: u64) -> ValueRef { C_uint(cx.isize_ty, i) } -pub fn C_u8(cx: &CodegenCx, i: u8) -> ValueRef { +pub fn C_u8(cx: &CodegenCx<'ll, '_>, i: u8) -> &'ll Value { C_uint(Type::i8(cx), i as u64) } // This is a 'c-like' raw string, which differs from // our boxed-and-length-annotated strings. -pub fn C_cstr(cx: &CodegenCx, s: LocalInternedString, null_terminated: bool) -> ValueRef { +pub fn C_cstr(cx: &CodegenCx<'ll, '_>, s: LocalInternedString, null_terminated: bool) -> &'ll Value { unsafe { if let Some(&llval) = cx.const_cstr_cache.borrow().get(&s) { return llval; @@ -209,24 +208,24 @@ pub fn C_cstr(cx: &CodegenCx, s: LocalInternedString, null_terminated: bool) -> // NB: Do not use `do_spill_noroot` to make this into a constant string, or // you will be kicked off fast isel. See issue #4352 for an example of this. -pub fn C_str_slice(cx: &CodegenCx, s: LocalInternedString) -> ValueRef { +pub fn C_str_slice(cx: &CodegenCx<'ll, '_>, s: LocalInternedString) -> &'ll Value { let len = s.len(); let cs = consts::ptrcast(C_cstr(cx, s, false), cx.layout_of(cx.tcx.mk_str()).llvm_type(cx).ptr_to()); C_fat_ptr(cx, cs, C_usize(cx, len as u64)) } -pub fn C_fat_ptr(cx: &CodegenCx, ptr: ValueRef, meta: ValueRef) -> ValueRef { +pub fn C_fat_ptr(cx: &CodegenCx<'ll, '_>, ptr: &'ll Value, meta: &'ll Value) -> &'ll Value { assert_eq!(abi::FAT_PTR_ADDR, 0); assert_eq!(abi::FAT_PTR_EXTRA, 1); C_struct(cx, &[ptr, meta], false) } -pub fn C_struct(cx: &CodegenCx, elts: &[ValueRef], packed: bool) -> ValueRef { +pub fn C_struct(cx: &CodegenCx<'ll, '_>, elts: &[&'ll Value], packed: bool) -> &'ll Value { C_struct_in_context(cx.llcx, elts, packed) } -pub fn C_struct_in_context(llcx: &llvm::Context, elts: &[ValueRef], packed: bool) -> ValueRef { +pub fn C_struct_in_context(llcx: &'ll llvm::Context, elts: &[&'ll Value], packed: bool) -> &'ll Value { unsafe { llvm::LLVMConstStructInContext(llcx, elts.as_ptr(), elts.len() as c_uint, @@ -234,43 +233,43 @@ pub fn C_struct_in_context(llcx: &llvm::Context, elts: &[ValueRef], packed: bool } } -pub fn C_array(ty: &Type, elts: &[ValueRef]) -> ValueRef { +pub fn C_array(ty: &'ll Type, elts: &[&'ll Value]) -> &'ll Value { unsafe { return llvm::LLVMConstArray(ty, elts.as_ptr(), elts.len() as c_uint); } } -pub fn C_vector(elts: &[ValueRef]) -> ValueRef { +pub fn C_vector(elts: &[&'ll Value]) -> &'ll Value { unsafe { return llvm::LLVMConstVector(elts.as_ptr(), elts.len() as c_uint); } } -pub fn C_bytes(cx: &CodegenCx, bytes: &[u8]) -> ValueRef { +pub fn C_bytes(cx: &CodegenCx<'ll, '_>, bytes: &[u8]) -> &'ll Value { C_bytes_in_context(cx.llcx, bytes) } -pub fn C_bytes_in_context(llcx: &llvm::Context, bytes: &[u8]) -> ValueRef { +pub fn C_bytes_in_context(llcx: &'ll llvm::Context, bytes: &[u8]) -> &'ll Value { unsafe { let ptr = bytes.as_ptr() as *const c_char; return llvm::LLVMConstStringInContext(llcx, ptr, bytes.len() as c_uint, True); } } -pub fn const_get_elt(v: ValueRef, idx: u64) -> ValueRef { +pub fn const_get_elt(v: &'ll Value, idx: u64) -> &'ll Value { unsafe { assert_eq!(idx as c_uint as u64, idx); let us = &[idx as c_uint]; let r = llvm::LLVMConstExtractValue(v, us.as_ptr(), us.len() as c_uint); debug!("const_get_elt(v={:?}, idx={}, r={:?})", - Value(v), idx, Value(r)); + v, idx, r); r } } -pub fn const_get_real(v: ValueRef) -> Option<(f64, bool)> { +pub fn const_get_real(v: &'ll Value) -> Option<(f64, bool)> { unsafe { if is_const_real(v) { let mut loses_info: llvm::Bool = ::std::mem::uninitialized(); @@ -283,21 +282,21 @@ pub fn const_get_real(v: ValueRef) -> Option<(f64, bool)> { } } -pub fn const_to_uint(v: ValueRef) -> u64 { +pub fn const_to_uint(v: &'ll Value) -> u64 { unsafe { llvm::LLVMConstIntGetZExtValue(v) } } -pub fn is_const_integral(v: ValueRef) -> bool { +pub fn is_const_integral(v: &'ll Value) -> bool { unsafe { - !llvm::LLVMIsAConstantInt(v).is_null() + llvm::LLVMIsAConstantInt(v).is_some() } } -pub fn is_const_real(v: ValueRef) -> bool { +pub fn is_const_real(v: &'ll Value) -> bool { unsafe { - !llvm::LLVMIsAConstantFP(v).is_null() + llvm::LLVMIsAConstantFP(v).is_some() } } @@ -307,7 +306,7 @@ fn hi_lo_to_u128(lo: u64, hi: u64) -> u128 { ((hi as u128) << 64) | (lo as u128) } -pub fn const_to_opt_u128(v: ValueRef, sign_ext: bool) -> Option { +pub fn const_to_opt_u128(v: &'ll Value, sign_ext: bool) -> Option { unsafe { if is_const_integral(v) { let (mut lo, mut hi) = (0u64, 0u64); @@ -348,9 +347,9 @@ pub fn langcall(tcx: TyCtxt, pub fn build_unchecked_lshift( bx: &Builder<'a, 'll, 'tcx>, - lhs: ValueRef, - rhs: ValueRef -) -> ValueRef { + lhs: &'ll Value, + rhs: &'ll Value +) -> &'ll Value { let rhs = base::cast_shift_expr_rhs(bx, hir::BinOpKind::Shl, lhs, rhs); // #1877, #10183: Ensure that input is always valid let rhs = shift_mask_rhs(bx, rhs); @@ -358,8 +357,8 @@ pub fn build_unchecked_lshift( } pub fn build_unchecked_rshift( - bx: &Builder<'a, 'll, 'tcx>, lhs_t: Ty<'tcx>, lhs: ValueRef, rhs: ValueRef -) -> ValueRef { + bx: &Builder<'a, 'll, 'tcx>, lhs_t: Ty<'tcx>, lhs: &'ll Value, rhs: &'ll Value +) -> &'ll Value { let rhs = base::cast_shift_expr_rhs(bx, hir::BinOpKind::Shr, lhs, rhs); // #1877, #10183: Ensure that input is always valid let rhs = shift_mask_rhs(bx, rhs); @@ -371,7 +370,7 @@ pub fn build_unchecked_rshift( } } -fn shift_mask_rhs(bx: &Builder<'a, 'll, 'tcx>, rhs: ValueRef) -> ValueRef { +fn shift_mask_rhs(bx: &Builder<'a, 'll, 'tcx>, rhs: &'ll Value) -> &'ll Value { let rhs_llty = val_ty(rhs); bx.and(rhs, shift_mask_val(bx, rhs_llty, rhs_llty, false)) } @@ -381,7 +380,7 @@ pub fn shift_mask_val( llty: &'ll Type, mask_llty: &'ll Type, invert: bool -) -> ValueRef { +) -> &'ll Value { let kind = llty.kind(); match kind { TypeKind::Integer => { diff --git a/src/librustc_codegen_llvm/consts.rs b/src/librustc_codegen_llvm/consts.rs index 956e81f746da9..72ff65361cada 100644 --- a/src/librustc_codegen_llvm/consts.rs +++ b/src/librustc_codegen_llvm/consts.rs @@ -9,9 +9,7 @@ // except according to those terms. use libc::c_uint; -use llvm; -use llvm::{SetUnnamedAddr}; -use llvm::{ValueRef, True}; +use llvm::{self, SetUnnamedAddr, True}; use rustc::hir::def_id::DefId; use rustc::hir::map as hir_map; use debuginfo; @@ -24,27 +22,29 @@ use syntax_pos::Span; use syntax_pos::symbol::LocalInternedString; use type_::Type; use type_of::LayoutLlvmExt; +use value::Value; use rustc::ty::{self, Ty}; + use rustc::ty::layout::{Align, LayoutOf}; use rustc::hir::{self, CodegenFnAttrs, CodegenFnAttrFlags}; use std::ffi::{CStr, CString}; -pub fn ptrcast(val: ValueRef, ty: &Type) -> ValueRef { +pub fn ptrcast(val: &'ll Value, ty: &'ll Type) -> &'ll Value { unsafe { llvm::LLVMConstPointerCast(val, ty) } } -pub fn bitcast(val: ValueRef, ty: &Type) -> ValueRef { +pub fn bitcast(val: &'ll Value, ty: &'ll Type) -> &'ll Value { unsafe { llvm::LLVMConstBitCast(val, ty) } } -fn set_global_alignment(cx: &CodegenCx, - gv: ValueRef, +fn set_global_alignment(cx: &CodegenCx<'ll, '_>, + gv: &'ll Value, mut align: Align) { // The target may require greater alignment for globals than the type does. // Note: GCC and Clang also allow `__attribute__((aligned))` on variables, @@ -62,11 +62,12 @@ fn set_global_alignment(cx: &CodegenCx, } } -pub fn addr_of_mut(cx: &CodegenCx, - cv: ValueRef, - align: Align, - kind: &str) - -> ValueRef { +pub fn addr_of_mut( + cx: &CodegenCx<'ll, '_>, + cv: &'ll Value, + align: Align, + kind: &str, +) -> &'ll Value { unsafe { let name = cx.generate_local_symbol_name(kind); let gv = declare::define_global(cx, &name[..], val_ty(cv)).unwrap_or_else(||{ @@ -80,11 +81,12 @@ pub fn addr_of_mut(cx: &CodegenCx, } } -pub fn addr_of(cx: &CodegenCx, - cv: ValueRef, - align: Align, - kind: &str) - -> ValueRef { +pub fn addr_of( + cx: &CodegenCx<'ll, '_>, + cv: &'ll Value, + align: Align, + kind: &str, +) -> &'ll Value { if let Some(&gv) = cx.const_globals.borrow().get(&cv) { unsafe { // Upgrade the alignment in cases where the same constant is used with different @@ -104,7 +106,7 @@ pub fn addr_of(cx: &CodegenCx, gv } -pub fn get_static(cx: &CodegenCx, def_id: DefId) -> ValueRef { +pub fn get_static(cx: &CodegenCx<'ll, '_>, def_id: DefId) -> &'ll Value { let instance = Instance::mono(cx.tcx, def_id); if let Some(&g) = cx.instances.borrow().get(&instance) { return g; @@ -213,13 +215,13 @@ pub fn get_static(cx: &CodegenCx, def_id: DefId) -> ValueRef { g } -fn check_and_apply_linkage<'tcx>( - cx: &CodegenCx<'_, 'tcx>, +fn check_and_apply_linkage( + cx: &CodegenCx<'ll, 'tcx>, attrs: &CodegenFnAttrs, ty: Ty<'tcx>, sym: LocalInternedString, span: Option -) -> ValueRef { +) -> &'ll Value { let llty = cx.layout_of(ty).llvm_type(cx); if let Some(linkage) = attrs.linkage { debug!("get_static: sym={} linkage={:?}", sym, linkage); diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs index 1616d54a77aaa..417af8b2b09ac 100644 --- a/src/librustc_codegen_llvm/context.rs +++ b/src/librustc_codegen_llvm/context.rs @@ -10,7 +10,6 @@ use common; use llvm; -use llvm::ValueRef; use rustc::dep_graph::DepGraphSafe; use rustc::hir; use rustc::hir::def_id::DefId; @@ -19,6 +18,7 @@ use callee; use base; use declare; use monomorphize::Instance; +use value::Value; use monomorphize::partitioning::CodegenUnit; use type_::Type; @@ -56,38 +56,38 @@ pub struct CodegenCx<'a, 'tcx: 'a> { pub codegen_unit: Arc>, /// Cache instances of monomorphic and polymorphic items - pub instances: RefCell, ValueRef>>, + pub instances: RefCell, &'a Value>>, /// Cache generated vtables pub vtables: RefCell, - Option>), ValueRef>>, + Option>), &'a Value>>, /// Cache of constant strings, - pub const_cstr_cache: RefCell>, + pub const_cstr_cache: RefCell>, /// Reverse-direction for const ptrs cast from globals. - /// Key is a ValueRef holding a *T, - /// Val is a ValueRef holding a *[T]. + /// Key is a Value holding a *T, + /// Val is a Value holding a *[T]. /// /// Needed because LLVM loses pointer->pointee association /// when we ptrcast, and we have to ptrcast during codegen /// of a [T] const because we form a slice, a (*T,usize) pair, not /// a pointer to an LLVM array type. Similar for trait objects. - pub const_unsized: RefCell>, + pub const_unsized: RefCell>, /// Cache of emitted const globals (value -> global) - pub const_globals: RefCell>, + pub const_globals: RefCell>, /// Mapping from static definitions to their DefId's. - pub statics: RefCell>, + pub statics: RefCell>, /// List of globals for static variables which need to be passed to the /// LLVM function ReplaceAllUsesWith (RAUW) when codegen is complete. - /// (We have to make sure we don't invalidate any ValueRefs referring + /// (We have to make sure we don't invalidate any Values referring /// to constants.) - pub statics_to_rauw: RefCell>, + pub statics_to_rauw: RefCell>, /// Statics that will be placed in the llvm.used variable /// See http://llvm.org/docs/LangRef.html#the-llvm-used-global-variable for details - pub used_statics: RefCell>, + pub used_statics: RefCell>, pub lltypes: RefCell, Option), &'a Type>>, pub scalar_lltypes: RefCell, &'a Type>>, @@ -96,11 +96,11 @@ pub struct CodegenCx<'a, 'tcx: 'a> { pub dbg_cx: Option>, - eh_personality: Cell>, - eh_unwind_resume: Cell>, - pub rust_try_fn: Cell>, + eh_personality: Cell>, + eh_unwind_resume: Cell>, + pub rust_try_fn: Cell>, - intrinsics: RefCell>, + intrinsics: RefCell>, /// A counter that is used for generating local symbol names local_gen_sym_counter: Cell, @@ -314,7 +314,7 @@ impl<'b, 'tcx> CodegenCx<'b, 'tcx> { &self.tcx.sess } - pub fn get_intrinsic(&self, key: &str) -> ValueRef { + pub fn get_intrinsic(&self, key: &str) -> &'b Value { if let Some(v) = self.intrinsics.borrow().get(key).cloned() { return v; } @@ -338,7 +338,7 @@ impl<'b, 'tcx> CodegenCx<'b, 'tcx> { name } - pub fn eh_personality(&self) -> ValueRef { + pub fn eh_personality(&self) -> &'b Value { // The exception handling personality function. // // If our compilation unit has the `eh_personality` lang item somewhere @@ -381,9 +381,9 @@ impl<'b, 'tcx> CodegenCx<'b, 'tcx> { llfn } - // Returns a ValueRef of the "eh_unwind_resume" lang item if one is defined, + // Returns a Value of the "eh_unwind_resume" lang item if one is defined, // otherwise declares it as an external function. - pub fn eh_unwind_resume(&self) -> ValueRef { + pub fn eh_unwind_resume(&self) -> &'b Value { use attributes; let unwresume = &self.eh_unwind_resume; if let Some(llfn) = unwresume.get() { @@ -471,7 +471,7 @@ impl LayoutOf for &'a CodegenCx<'ll, 'tcx> { } /// Declare any llvm intrinsics that you might need -fn declare_intrinsic(cx: &CodegenCx, key: &str) -> Option { +fn declare_intrinsic(cx: &CodegenCx<'ll, '_>, key: &str) -> Option<&'ll Value> { macro_rules! ifn { ($name:expr, fn() -> $ret:expr) => ( if key == $name { diff --git a/src/librustc_codegen_llvm/debuginfo/gdb.rs b/src/librustc_codegen_llvm/debuginfo/gdb.rs index de43a4522cc28..08128a729b5f0 100644 --- a/src/librustc_codegen_llvm/debuginfo/gdb.rs +++ b/src/librustc_codegen_llvm/debuginfo/gdb.rs @@ -15,8 +15,9 @@ use llvm; use common::{C_bytes, CodegenCx, C_i32}; use builder::Builder; use declare; -use type_::Type; use rustc::session::config::NoDebugInfo; +use type_::Type; +use value::Value; use syntax::attr; @@ -39,8 +40,8 @@ pub fn insert_reference_to_gdb_debug_scripts_section_global(bx: &Builder) { /// Allocates the global variable responsible for the .debug_gdb_scripts binary /// section. -pub fn get_or_insert_gdb_debug_scripts_section_global(cx: &CodegenCx) - -> llvm::ValueRef { +pub fn get_or_insert_gdb_debug_scripts_section_global(cx: &CodegenCx<'ll, '_>) + -> &'ll Value { let c_section_var_name = "__rustc_debug_gdb_scripts_section__\0"; let section_var_name = &c_section_var_name[..c_section_var_name.len()-1]; @@ -49,7 +50,7 @@ pub fn get_or_insert_gdb_debug_scripts_section_global(cx: &CodegenCx) c_section_var_name.as_ptr() as *const _) }; - if section_var.is_null() { + section_var.unwrap_or_else(|| { let section_name = b".debug_gdb_scripts\0"; let section_contents = b"\x01gdb_load_rust_pretty_printers.py\0"; @@ -71,9 +72,7 @@ pub fn get_or_insert_gdb_debug_scripts_section_global(cx: &CodegenCx) llvm::LLVMSetAlignment(section_var, 1); section_var } - } else { - section_var - } + }) } pub fn needs_gdb_debug_scripts_section(cx: &CodegenCx) -> bool { diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs index ae2e350dc651c..69ef92ed98e52 100644 --- a/src/librustc_codegen_llvm/debuginfo/metadata.rs +++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs @@ -18,8 +18,9 @@ use super::namespace::mangled_name_of_instance; use super::type_names::compute_debuginfo_type_name; use super::{CrateDebugContext}; use abi; +use value::Value; -use llvm::{self, ValueRef}; +use llvm; use llvm::debuginfo::{DIType, DIFile, DIScope, DIDescriptor, DICompositeType, DILexicalBlock, DIFlags}; @@ -890,7 +891,7 @@ pub fn compile_unit_metadata(tcx: TyCtxt, return unit_metadata; }; - fn path_to_mdstring(llcx: &llvm::Context, path: &Path) -> llvm::ValueRef { + fn path_to_mdstring(llcx: &'ll llvm::Context, path: &Path) -> &'ll Value { let path_str = path2cstr(path); unsafe { llvm::LLVMMDStringInContext(llcx, @@ -1679,9 +1680,11 @@ fn create_union_stub( /// Creates debug information for the given global variable. /// /// Adds the created metadata nodes directly to the crate's IR. -pub fn create_global_var_metadata(cx: &CodegenCx, - def_id: DefId, - global: ValueRef) { +pub fn create_global_var_metadata( + cx: &CodegenCx<'ll, '_>, + def_id: DefId, + global: &'ll Value, +) { if cx.dbg_cx.is_none() { return; } @@ -1759,9 +1762,11 @@ pub fn extend_scope_to_file( /// given type. /// /// Adds the created metadata nodes directly to the crate's IR. -pub fn create_vtable_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, - ty: ty::Ty<'tcx>, - vtable: ValueRef) { +pub fn create_vtable_metadata( + cx: &CodegenCx<'ll, 'tcx>, + ty: ty::Ty<'tcx>, + vtable: &'ll Value, +) { if cx.dbg_cx.is_none() { return; } diff --git a/src/librustc_codegen_llvm/debuginfo/mod.rs b/src/librustc_codegen_llvm/debuginfo/mod.rs index 27a4c60b36df3..3b6b7b2d77b1c 100644 --- a/src/librustc_codegen_llvm/debuginfo/mod.rs +++ b/src/librustc_codegen_llvm/debuginfo/mod.rs @@ -21,7 +21,6 @@ use self::metadata::{type_metadata, file_metadata, TypeMap}; use self::source_loc::InternalDebugLocation::{self, UnknownLocation}; use llvm; -use llvm::ValueRef; use llvm::debuginfo::{DIFile, DIType, DIScope, DIBuilder, DISubprogram, DIArray, DIFlags}; use rustc::hir::CodegenFnAttrFlags; use rustc::hir::def_id::{DefId, CrateNum}; @@ -35,6 +34,7 @@ use rustc::ty::{self, ParamEnv, Ty, InstanceDef}; use rustc::mir; use rustc::session::config::{self, FullDebugInfo, LimitedDebugInfo, NoDebugInfo}; use rustc::util::nodemap::{DefIdMap, FxHashMap, FxHashSet}; +use value::Value; use libc::c_uint; use std::cell::{Cell, RefCell}; @@ -135,12 +135,12 @@ pub struct FunctionDebugContextData<'ll> { pub defining_crate: CrateNum, } -pub enum VariableAccess<'a> { +pub enum VariableAccess<'a, 'll> { // The llptr given is an alloca containing the variable's value - DirectVariable { alloca: ValueRef }, + DirectVariable { alloca: &'ll Value }, // The llptr given is an alloca containing the start of some pointer chain // leading to the variable's content. - IndirectVariable { alloca: ValueRef, address_operations: &'a [i64] } + IndirectVariable { alloca: &'ll Value, address_operations: &'a [i64] } } pub enum VariableKind { @@ -204,7 +204,7 @@ pub fn create_function_debug_context( cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>, sig: ty::FnSig<'tcx>, - llfn: ValueRef, + llfn: &'ll Value, mir: &mir::Mir, ) -> FunctionDebugContext<'ll> { if cx.sess().opts.debuginfo == NoDebugInfo { @@ -482,7 +482,7 @@ pub fn declare_local( variable_name: ast::Name, variable_type: Ty<'tcx>, scope_metadata: &'ll DIScope, - variable_access: VariableAccess, + variable_access: VariableAccess<'_, 'll>, variable_kind: VariableKind, span: Span, ) { diff --git a/src/librustc_codegen_llvm/debuginfo/source_loc.rs b/src/librustc_codegen_llvm/debuginfo/source_loc.rs index ae117ffd3ecd1..55cf139394344 100644 --- a/src/librustc_codegen_llvm/debuginfo/source_loc.rs +++ b/src/librustc_codegen_llvm/debuginfo/source_loc.rs @@ -19,7 +19,6 @@ use llvm::debuginfo::DIScope; use builder::Builder; use libc::c_uint; -use std::ptr::NonNull; use syntax_pos::{Span, Pos}; /// Sets the current debug location at the beginning of the span. @@ -96,7 +95,7 @@ pub fn set_debug_location(bx: &Builder<'_, 'll, '_>, debug_location: InternalDeb debug!("setting debug location to {} {}", line, col); unsafe { - NonNull::new(llvm::LLVMRustDIBuilderCreateDebugLocation( + Some(llvm::LLVMRustDIBuilderCreateDebugLocation( debug_context(bx.cx).llcontext, line as c_uint, col_used, diff --git a/src/librustc_codegen_llvm/declare.rs b/src/librustc_codegen_llvm/declare.rs index 1a9346ed8933d..c7cd06669fab1 100644 --- a/src/librustc_codegen_llvm/declare.rs +++ b/src/librustc_codegen_llvm/declare.rs @@ -16,11 +16,11 @@ //! Some useful guidelines: //! //! * Use declare_* family of methods if you are declaring, but are not -//! interested in defining the ValueRef they return. -//! * Use define_* family of methods when you might be defining the ValueRef. +//! interested in defining the Value they return. +//! * Use define_* family of methods when you might be defining the Value. //! * When in doubt, define. -use llvm::{self, ValueRef}; +use llvm; use llvm::AttributePlace::Function; use rustc::ty::{self, Ty}; use rustc::ty::layout::{self, LayoutOf}; @@ -39,8 +39,8 @@ use std::ffi::CString; /// Declare a global value. /// /// If there’s a value with the same name already declared, the function will -/// return its ValueRef instead. -pub fn declare_global(cx: &CodegenCx, name: &str, ty: &Type) -> llvm::ValueRef { +/// return its Value instead. +pub fn declare_global(cx: &CodegenCx<'ll, '_>, name: &str, ty: &'ll Type) -> &'ll Value { debug!("declare_global(name={:?})", name); let namebuf = CString::new(name).unwrap_or_else(|_|{ bug!("name {:?} contains an interior null byte", name) @@ -54,8 +54,8 @@ pub fn declare_global(cx: &CodegenCx, name: &str, ty: &Type) -> llvm::ValueRef { /// Declare a function. /// /// If there’s a value with the same name already declared, the function will -/// update the declaration and return existing ValueRef instead. -fn declare_raw_fn(cx: &CodegenCx, name: &str, callconv: llvm::CallConv, ty: &Type) -> ValueRef { +/// update the declaration and return existing Value instead. +fn declare_raw_fn(cx: &CodegenCx<'ll, '_>, name: &str, callconv: llvm::CallConv, ty: &'ll Type) -> &'ll Value { debug!("declare_raw_fn(name={:?}, ty={:?})", name, ty); let namebuf = CString::new(name).unwrap_or_else(|_|{ bug!("name {:?} contains an interior null byte", name) @@ -114,8 +114,8 @@ fn declare_raw_fn(cx: &CodegenCx, name: &str, callconv: llvm::CallConv, ty: &Typ /// `declare_fn` instead. /// /// If there’s a value with the same name already declared, the function will -/// update the declaration and return existing ValueRef instead. -pub fn declare_cfn(cx: &CodegenCx, name: &str, fn_type: &Type) -> ValueRef { +/// update the declaration and return existing Value instead. +pub fn declare_cfn(cx: &CodegenCx<'ll, '_>, name: &str, fn_type: &'ll Type) -> &'ll Value { declare_raw_fn(cx, name, llvm::CCallConv, fn_type) } @@ -123,9 +123,12 @@ pub fn declare_cfn(cx: &CodegenCx, name: &str, fn_type: &Type) -> ValueRef { /// Declare a Rust function. /// /// If there’s a value with the same name already declared, the function will -/// update the declaration and return existing ValueRef instead. -pub fn declare_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, name: &str, - fn_type: Ty<'tcx>) -> ValueRef { +/// update the declaration and return existing Value instead. +pub fn declare_fn( + cx: &CodegenCx<'ll, 'tcx>, + name: &str, + fn_type: Ty<'tcx>, +) -> &'ll Value { debug!("declare_rust_fn(name={:?}, fn_type={:?})", name, fn_type); let sig = common::ty_fn_sig(cx, fn_type); let sig = cx.tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig); @@ -154,7 +157,7 @@ pub fn declare_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, name: &str, /// return None if the name already has a definition associated with it. In that /// case an error should be reported to the user, because it usually happens due /// to user’s fault (e.g. misuse of #[no_mangle] or #[export_name] attributes). -pub fn define_global(cx: &CodegenCx, name: &str, ty: &Type) -> Option { +pub fn define_global(cx: &CodegenCx<'ll, '_>, name: &str, ty: &'ll Type) -> Option<&'ll Value> { if get_defined_value(cx, name).is_some() { None } else { @@ -167,9 +170,11 @@ pub fn define_global(cx: &CodegenCx, name: &str, ty: &Type) -> Option /// Use this function when you intend to define a function. This function will /// return panic if the name already has a definition associated with it. This /// can happen with #[no_mangle] or #[export_name], for example. -pub fn define_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, - name: &str, - fn_type: Ty<'tcx>) -> ValueRef { +pub fn define_fn( + cx: &CodegenCx<'ll, 'tcx>, + name: &str, + fn_type: Ty<'tcx>, +) -> &'ll Value { if get_defined_value(cx, name).is_some() { cx.sess().fatal(&format!("symbol `{}` already defined", name)) } else { @@ -182,9 +187,11 @@ pub fn define_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, /// Use this function when you intend to define a function. This function will /// return panic if the name already has a definition associated with it. This /// can happen with #[no_mangle] or #[export_name], for example. -pub fn define_internal_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, - name: &str, - fn_type: Ty<'tcx>) -> ValueRef { +pub fn define_internal_fn( + cx: &CodegenCx<'ll, 'tcx>, + name: &str, + fn_type: Ty<'tcx>, +) -> &'ll Value { let llfn = define_fn(cx, name, fn_type); unsafe { llvm::LLVMRustSetLinkage(llfn, llvm::Linkage::InternalLinkage) }; llfn @@ -192,24 +199,17 @@ pub fn define_internal_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, /// Get declared value by name. -pub fn get_declared_value(cx: &CodegenCx, name: &str) -> Option { +pub fn get_declared_value(cx: &CodegenCx<'ll, '_>, name: &str) -> Option<&'ll Value> { debug!("get_declared_value(name={:?})", name); let namebuf = CString::new(name).unwrap_or_else(|_|{ bug!("name {:?} contains an interior null byte", name) }); - let val = unsafe { llvm::LLVMRustGetNamedValue(cx.llmod, namebuf.as_ptr()) }; - if val.is_null() { - debug!("get_declared_value: {:?} value is null", name); - None - } else { - debug!("get_declared_value: {:?} => {:?}", name, Value(val)); - Some(val) - } + unsafe { llvm::LLVMRustGetNamedValue(cx.llmod, namebuf.as_ptr()) } } /// Get defined or externally defined (AvailableExternally linkage) value by /// name. -pub fn get_defined_value(cx: &CodegenCx, name: &str) -> Option { +pub fn get_defined_value(cx: &CodegenCx<'ll, '_>, name: &str) -> Option<&'ll Value> { get_declared_value(cx, name).and_then(|val|{ let declaration = unsafe { llvm::LLVMIsDeclaration(val) != 0 diff --git a/src/librustc_codegen_llvm/glue.rs b/src/librustc_codegen_llvm/glue.rs index 992ff9f24de13..37ce51da77823 100644 --- a/src/librustc_codegen_llvm/glue.rs +++ b/src/librustc_codegen_llvm/glue.rs @@ -16,37 +16,36 @@ use std; use builder::Builder; use common::*; -use llvm::{ValueRef}; use llvm; use meth; use rustc::ty::layout::LayoutOf; use rustc::ty::{self, Ty}; use value::Value; -pub fn size_and_align_of_dst(bx: &Builder<'a, 'll, 'tcx>, t: Ty<'tcx>, info: ValueRef) - -> (ValueRef, ValueRef) { +pub fn size_and_align_of_dst(bx: &Builder<'_, 'll, 'tcx>, t: Ty<'tcx>, info: Option<&'ll Value>) + -> (&'ll Value, &'ll Value) { debug!("calculate size of DST: {}; with lost info: {:?}", - t, Value(info)); + t, info); if bx.cx.type_is_sized(t) { let (size, align) = bx.cx.size_and_align_of(t); debug!("size_and_align_of_dst t={} info={:?} size: {:?} align: {:?}", - t, Value(info), size, align); + t, info, size, align); let size = C_usize(bx.cx, size.bytes()); let align = C_usize(bx.cx, align.abi()); return (size, align); } - assert!(!info.is_null()); match t.sty { ty::TyDynamic(..) => { // load size/align from vtable - (meth::SIZE.get_usize(bx, info), meth::ALIGN.get_usize(bx, info)) + let vtable = info.unwrap(); + (meth::SIZE.get_usize(bx, vtable), meth::ALIGN.get_usize(bx, vtable)) } ty::TySlice(_) | ty::TyStr => { let unit = t.sequence_element_type(bx.tcx()); // The info in this case is the length of the str, so the size is that // times the unit size. let (size, align) = bx.cx.size_and_align_of(unit); - (bx.mul(info, C_usize(bx.cx, size.bytes())), + (bx.mul(info.unwrap(), C_usize(bx.cx, size.bytes())), C_usize(bx.cx, align.abi())) } _ => { diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index e52ebc7f34bea..06a5c34a4cae0 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -11,8 +11,7 @@ #![allow(non_upper_case_globals)] use intrinsics::{self, Intrinsic}; -use llvm; -use llvm::{TypeKind, ValueRef}; +use llvm::{self, TypeKind}; use abi::{Abi, FnType, LlvmType, PassMode}; use mir::place::PlaceRef; use mir::operand::{OperandRef, OperandValue}; @@ -28,6 +27,7 @@ use rustc::hir; use syntax::ast; use syntax::symbol::Symbol; use builder::Builder; +use value::Value; use rustc::session::Session; use syntax_pos::Span; @@ -35,7 +35,7 @@ use syntax_pos::Span; use std::cmp::Ordering; use std::iter; -fn get_simple_intrinsic(cx: &CodegenCx, name: &str) -> Option { +fn get_simple_intrinsic(cx: &CodegenCx<'ll, '_>, name: &str) -> Option<&'ll Value> { let llvm_name = match name { "sqrtf32" => "llvm.sqrt.f32", "sqrtf64" => "llvm.sqrt.f64", @@ -89,8 +89,8 @@ pub fn codegen_intrinsic_call( bx: &Builder<'a, 'll, 'tcx>, callee_ty: Ty<'tcx>, fn_ty: &FnType<'tcx, Ty<'tcx>>, - args: &[OperandRef<'tcx>], - llresult: ValueRef, + args: &[OperandRef<'ll, 'tcx>], + llresult: &'ll Value, span: Span, ) { let cx = bx.cx; @@ -148,7 +148,7 @@ pub fn codegen_intrinsic_call( let tp_ty = substs.type_at(0); if let OperandValue::Pair(_, meta) = args[0].val { let (llsize, _) = - glue::size_and_align_of_dst(bx, tp_ty, meta); + glue::size_and_align_of_dst(bx, tp_ty, Some(meta)); llsize } else { C_usize(cx, cx.size_of(tp_ty).bytes()) @@ -162,7 +162,7 @@ pub fn codegen_intrinsic_call( let tp_ty = substs.type_at(0); if let OperandValue::Pair(_, meta) = args[0].val { let (_, llalign) = - glue::size_and_align_of_dst(bx, tp_ty, meta); + glue::size_and_align_of_dst(bx, tp_ty, Some(meta)); llalign } else { C_usize(cx, cx.align_of(tp_ty).abi()) @@ -592,9 +592,8 @@ pub fn codegen_intrinsic_call( fn modify_as_needed( bx: &Builder<'a, 'll, 'tcx>, t: &intrinsics::Type, - arg: &OperandRef<'tcx>, - ) -> Vec - { + arg: &OperandRef<'ll, 'tcx>, + ) -> Vec<&'ll Value> { match *t { intrinsics::Type::Aggregate(true, ref contents) => { // We found a tuple that needs squishing! So @@ -685,10 +684,10 @@ fn copy_intrinsic( allow_overlap: bool, volatile: bool, ty: Ty<'tcx>, - dst: ValueRef, - src: ValueRef, - count: ValueRef, -) -> ValueRef { + dst: &'ll Value, + src: &'ll Value, + count: &'ll Value, +) -> &'ll Value { let cx = bx.cx; let (size, align) = cx.size_and_align_of(ty); let size = C_usize(cx, size.bytes()); @@ -720,10 +719,10 @@ fn memset_intrinsic( bx: &Builder<'a, 'll, 'tcx>, volatile: bool, ty: Ty<'tcx>, - dst: ValueRef, - val: ValueRef, - count: ValueRef -) -> ValueRef { + dst: &'ll Value, + val: &'ll Value, + count: &'ll Value +) -> &'ll Value { let cx = bx.cx; let (size, align) = cx.size_and_align_of(ty); let size = C_usize(cx, size.bytes()); @@ -734,11 +733,11 @@ fn memset_intrinsic( fn try_intrinsic( bx: &Builder<'a, 'll, 'tcx>, - cx: &CodegenCx, - func: ValueRef, - data: ValueRef, - local_ptr: ValueRef, - dest: ValueRef, + cx: &CodegenCx<'ll, 'tcx>, + func: &'ll Value, + data: &'ll Value, + local_ptr: &'ll Value, + dest: &'ll Value, ) { if bx.sess().no_landing_pads() { bx.call(func, &[data], None); @@ -760,11 +759,11 @@ fn try_intrinsic( // as the old ones are still more optimized. fn codegen_msvc_try( bx: &Builder<'a, 'll, 'tcx>, - cx: &CodegenCx, - func: ValueRef, - data: ValueRef, - local_ptr: ValueRef, - dest: ValueRef, + cx: &CodegenCx<'ll, 'tcx>, + func: &'ll Value, + data: &'ll Value, + local_ptr: &'ll Value, + dest: &'ll Value, ) { let llfn = get_rust_try_fn(cx, &mut |bx| { let cx = bx.cx; @@ -870,11 +869,11 @@ fn codegen_msvc_try( // the right personality function. fn codegen_gnu_try( bx: &Builder<'a, 'll, 'tcx>, - cx: &CodegenCx, - func: ValueRef, - data: ValueRef, - local_ptr: ValueRef, - dest: ValueRef, + cx: &CodegenCx<'ll, 'tcx>, + func: &'ll Value, + data: &'ll Value, + local_ptr: &'ll Value, + dest: &'ll Value, ) { let llfn = get_rust_try_fn(cx, &mut |bx| { let cx = bx.cx; @@ -936,7 +935,7 @@ fn gen_fn<'ll, 'tcx>( inputs: Vec>, output: Ty<'tcx>, codegen: &mut dyn FnMut(Builder<'_, 'll, 'tcx>), -) -> ValueRef { +) -> &'ll Value { let rust_fn_ty = cx.tcx.mk_fn_ptr(ty::Binder::bind(cx.tcx.mk_fn_sig( inputs.into_iter(), output, @@ -957,7 +956,7 @@ fn gen_fn<'ll, 'tcx>( fn get_rust_try_fn<'ll, 'tcx>( cx: &CodegenCx<'ll, 'tcx>, codegen: &mut dyn FnMut(Builder<'_, 'll, 'tcx>), -) -> ValueRef { +) -> &'ll Value { if let Some(llfn) = cx.rust_try_fn.get() { return llfn; } @@ -986,11 +985,11 @@ fn generic_simd_intrinsic( bx: &Builder<'a, 'll, 'tcx>, name: &str, callee_ty: Ty<'tcx>, - args: &[OperandRef<'tcx>], + args: &[OperandRef<'ll, 'tcx>], ret_ty: Ty<'tcx>, llret_ty: &'ll Type, span: Span -) -> Result { +) -> Result<&'ll Value, ()> { // macros for error handling: macro_rules! emit_error { ($msg: tt) => { @@ -1167,8 +1166,8 @@ fn generic_simd_intrinsic( in_len: usize, bx: &Builder<'a, 'll, 'tcx>, span: Span, - args: &[OperandRef<'tcx>], - ) -> Result { + args: &[OperandRef<'ll, 'tcx>], + ) -> Result<&'ll Value, ()> { macro_rules! emit_error { ($msg: tt) => { emit_error!($msg, ) diff --git a/src/librustc_codegen_llvm/llvm/diagnostic.rs b/src/librustc_codegen_llvm/llvm/diagnostic.rs index 99175864b39a0..e4c278442d91c 100644 --- a/src/librustc_codegen_llvm/llvm/diagnostic.rs +++ b/src/librustc_codegen_llvm/llvm/diagnostic.rs @@ -14,8 +14,9 @@ pub use self::OptimizationDiagnosticKind::*; pub use self::Diagnostic::*; use libc::c_uint; +use value::Value; -use super::{DiagnosticInfoRef, TwineRef, ValueRef}; +use super::{DiagnosticInfoRef, TwineRef}; #[derive(Copy, Clone)] pub enum OptimizationDiagnosticKind { @@ -41,21 +42,22 @@ impl OptimizationDiagnosticKind { } } -pub struct OptimizationDiagnostic { +pub struct OptimizationDiagnostic<'ll> { pub kind: OptimizationDiagnosticKind, pub pass_name: String, - pub function: ValueRef, + pub function: &'ll Value, 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 = 0 as *mut _; +impl OptimizationDiagnostic<'ll> { + unsafe fn unpack( + kind: OptimizationDiagnosticKind, + di: DiagnosticInfoRef, + ) -> Self { + let mut function = None; let mut line = 0; let mut column = 0; @@ -83,7 +85,7 @@ impl OptimizationDiagnostic { OptimizationDiagnostic { kind, pass_name: pass_name.expect("got a non-UTF8 pass name from LLVM"), - function, + function: function.unwrap(), line, column, filename, @@ -93,41 +95,44 @@ impl OptimizationDiagnostic { } #[derive(Copy, Clone)] -pub struct InlineAsmDiagnostic { +pub struct InlineAsmDiagnostic<'ll> { pub cookie: c_uint, pub message: TwineRef, - pub instruction: ValueRef, + pub instruction: &'ll Value, } -impl InlineAsmDiagnostic { - unsafe fn unpack(di: DiagnosticInfoRef) -> InlineAsmDiagnostic { - - let mut opt = InlineAsmDiagnostic { - cookie: 0, - message: 0 as *mut _, - instruction: 0 as *mut _, - }; - - super::LLVMRustUnpackInlineAsmDiagnostic(di, - &mut opt.cookie, - &mut opt.message, - &mut opt.instruction); +impl InlineAsmDiagnostic<'ll> { + unsafe fn unpack(di: DiagnosticInfoRef) -> Self { + let mut cookie = 0; + let mut message = 0 as *mut _; + let mut instruction = None; + + super::LLVMRustUnpackInlineAsmDiagnostic( + di, + &mut cookie, + &mut message, + &mut instruction, + ); - opt + InlineAsmDiagnostic { + cookie, + message, + instruction: instruction.unwrap(), + } } } -pub enum Diagnostic { - Optimization(OptimizationDiagnostic), - InlineAsm(InlineAsmDiagnostic), +pub enum Diagnostic<'ll> { + Optimization(OptimizationDiagnostic<'ll>), + InlineAsm(InlineAsmDiagnostic<'ll>), PGO(DiagnosticInfoRef), /// LLVM has other types that we do not wrap here. UnknownDiagnostic(DiagnosticInfoRef), } -impl Diagnostic { - pub unsafe fn unpack(di: DiagnosticInfoRef) -> Diagnostic { +impl Diagnostic<'ll> { + pub unsafe fn unpack(di: DiagnosticInfoRef) -> Self { use super::DiagnosticKind as Dk; let kind = super::LLVMRustGetDiagInfoKind(di); diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index 63f09a7e53a20..bf016bb8e3c6a 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -379,7 +379,6 @@ extern { pub type Module; } extern { pub type Context; } extern { pub type Type; } extern { pub type Value; } -pub type ValueRef = *mut Value; extern { pub type Metadata; } extern { pub type BasicBlock; } pub type BasicBlockRef = *mut BasicBlock; @@ -553,38 +552,38 @@ extern "C" { // Operations on all values pub fn LLVMTypeOf(Val: &Value) -> &Type; - 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); + pub fn LLVMGetValueName(Val: &Value) -> *const c_char; + pub fn LLVMSetValueName(Val: &Value, Name: *const c_char); + pub fn LLVMReplaceAllUsesWith(OldVal: &'a Value, NewVal: &'a Value); + pub fn LLVMSetMetadata(Val: &'a Value, KindID: c_uint, Node: &'a Value); // Operations on Uses - pub fn LLVMGetFirstUse(Val: ValueRef) -> UseRef; + pub fn LLVMGetFirstUse(Val: &Value) -> UseRef; pub fn LLVMGetNextUse(U: UseRef) -> UseRef; - pub fn LLVMGetUser(U: UseRef) -> ValueRef; + pub fn LLVMGetUser(U: UseRef) -> &'a Value; // Operations on Users - pub fn LLVMGetOperand(Val: ValueRef, Index: c_uint) -> ValueRef; + pub fn LLVMGetOperand(Val: &Value, Index: c_uint) -> &Value; // Operations on constants of any type - pub fn LLVMConstNull(Ty: &Type) -> 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: &Type) -> ValueRef; + pub fn LLVMConstNull(Ty: &Type) -> &Value; + pub fn LLVMConstICmp(Pred: IntPredicate, V1: &'a Value, V2: &'a Value) -> &'a Value; + pub fn LLVMConstFCmp(Pred: RealPredicate, V1: &'a Value, V2: &'a Value) -> &'a Value; + pub fn LLVMGetUndef(Ty: &Type) -> &Value; // Operations on metadata - pub fn LLVMMDStringInContext(C: &Context, Str: *const c_char, SLen: c_uint) -> ValueRef; - pub fn LLVMMDNodeInContext(C: &Context, Vals: *const ValueRef, Count: c_uint) -> ValueRef; - pub fn LLVMAddNamedMetadataOperand(M: &Module, Name: *const c_char, Val: ValueRef); + pub fn LLVMMDStringInContext(C: &Context, Str: *const c_char, SLen: c_uint) -> &Value; + pub fn LLVMMDNodeInContext(C: &'a Context, Vals: *const &'a Value, Count: c_uint) -> &'a Value; + pub fn LLVMAddNamedMetadataOperand(M: &'a Module, Name: *const c_char, Val: &'a Value); // Operations on scalar constants - pub fn LLVMConstInt(IntTy: &Type, N: c_ulonglong, SignExtend: Bool) -> ValueRef; - pub fn LLVMConstIntOfArbitraryPrecision(IntTy: &Type, 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, + pub fn LLVMConstInt(IntTy: &Type, N: c_ulonglong, SignExtend: Bool) -> &Value; + pub fn LLVMConstIntOfArbitraryPrecision(IntTy: &Type, Wn: c_uint, Ws: *const u64) -> &Value; + pub fn LLVMConstIntGetZExtValue(ConstantVal: &Value) -> c_ulonglong; + pub fn LLVMConstIntGetSExtValue(ConstantVal: &Value) -> c_longlong; + pub fn LLVMRustConstInt128Get(ConstantVal: &Value, SExt: bool, high: *mut u64, low: *mut u64) -> bool; - pub fn LLVMConstRealGetDouble (ConstantVal: ValueRef, losesInfo: *mut Bool) -> f64; + pub fn LLVMConstRealGetDouble (ConstantVal: &Value, losesInfo: *mut Bool) -> f64; // Operations on composite constants @@ -592,663 +591,663 @@ extern "C" { Str: *const c_char, Length: c_uint, DontNullTerminate: Bool) - -> ValueRef; - pub fn LLVMConstStructInContext(C: &Context, - ConstantVals: *const ValueRef, + -> &Value; + pub fn LLVMConstStructInContext(C: &'a Context, + ConstantVals: *const &'a Value, Count: c_uint, Packed: Bool) - -> ValueRef; + -> &'a Value; - pub fn LLVMConstArray(ElementTy: &Type, - ConstantVals: *const ValueRef, + pub fn LLVMConstArray(ElementTy: &'a Type, + ConstantVals: *const &'a Value, Length: c_uint) - -> ValueRef; - pub fn LLVMConstVector(ScalarConstantVals: *const ValueRef, Size: c_uint) -> ValueRef; + -> &'a Value; + pub fn LLVMConstVector(ScalarConstantVals: *const &Value, Size: c_uint) -> &Value; // Constant expressions - pub fn LLVMSizeOf(Ty: &Type) -> 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 LLVMSizeOf(Ty: &Type) -> &Value; + pub fn LLVMConstNeg(ConstantVal: &Value) -> &Value; + pub fn LLVMConstFNeg(ConstantVal: &Value) -> &Value; + pub fn LLVMConstNot(ConstantVal: &Value) -> &Value; + pub fn LLVMConstAdd(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; + pub fn LLVMConstFAdd(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; + pub fn LLVMConstSub(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; + pub fn LLVMConstFSub(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; + pub fn LLVMConstMul(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; + pub fn LLVMConstFMul(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; + pub fn LLVMConstUDiv(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; + pub fn LLVMConstSDiv(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; + pub fn LLVMConstFDiv(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; + pub fn LLVMConstURem(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; + pub fn LLVMConstSRem(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; + pub fn LLVMConstFRem(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; + pub fn LLVMConstAnd(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; + pub fn LLVMConstOr(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; + pub fn LLVMConstXor(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; + pub fn LLVMConstShl(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; + pub fn LLVMConstLShr(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; + pub fn LLVMConstAShr(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; pub fn LLVMConstGEP( - ConstantVal: ValueRef, - ConstantIndices: *const ValueRef, + ConstantVal: &'a Value, + ConstantIndices: *const &'a Value, NumIndices: c_uint, - ) -> ValueRef; + ) -> &'a Value; pub fn LLVMConstInBoundsGEP( - ConstantVal: ValueRef, - ConstantIndices: *const ValueRef, + ConstantVal: &'a Value, + ConstantIndices: *const &'a Value, NumIndices: c_uint, - ) -> ValueRef; - pub fn LLVMConstTrunc(ConstantVal: ValueRef, ToType: &Type) -> ValueRef; - pub fn LLVMConstZExt(ConstantVal: ValueRef, ToType: &Type) -> ValueRef; - pub fn LLVMConstUIToFP(ConstantVal: ValueRef, ToType: &Type) -> ValueRef; - pub fn LLVMConstSIToFP(ConstantVal: ValueRef, ToType: &Type) -> ValueRef; - pub fn LLVMConstFPToUI(ConstantVal: ValueRef, ToType: &Type) -> ValueRef; - pub fn LLVMConstFPToSI(ConstantVal: ValueRef, ToType: &Type) -> ValueRef; - pub fn LLVMConstPtrToInt(ConstantVal: ValueRef, ToType: &Type) -> ValueRef; - pub fn LLVMConstIntToPtr(ConstantVal: ValueRef, ToType: &Type) -> ValueRef; - pub fn LLVMConstBitCast(ConstantVal: ValueRef, ToType: &Type) -> ValueRef; - pub fn LLVMConstPointerCast(ConstantVal: ValueRef, ToType: &Type) -> ValueRef; - pub fn LLVMConstIntCast(ConstantVal: ValueRef, ToType: &Type, isSigned: Bool) -> ValueRef; - pub fn LLVMConstFPCast(ConstantVal: ValueRef, ToType: &Type) -> ValueRef; - pub fn LLVMConstExtractValue(AggConstant: ValueRef, + ) -> &'a Value; + pub fn LLVMConstTrunc(ConstantVal: &'a Value, ToType: &'a Type) -> &'a Value; + pub fn LLVMConstZExt(ConstantVal: &'a Value, ToType: &'a Type) -> &'a Value; + pub fn LLVMConstUIToFP(ConstantVal: &'a Value, ToType: &'a Type) -> &'a Value; + pub fn LLVMConstSIToFP(ConstantVal: &'a Value, ToType: &'a Type) -> &'a Value; + pub fn LLVMConstFPToUI(ConstantVal: &'a Value, ToType: &'a Type) -> &'a Value; + pub fn LLVMConstFPToSI(ConstantVal: &'a Value, ToType: &'a Type) -> &'a Value; + pub fn LLVMConstPtrToInt(ConstantVal: &'a Value, ToType: &'a Type) -> &'a Value; + pub fn LLVMConstIntToPtr(ConstantVal: &'a Value, ToType: &'a Type) -> &'a Value; + pub fn LLVMConstBitCast(ConstantVal: &'a Value, ToType: &'a Type) -> &'a Value; + pub fn LLVMConstPointerCast(ConstantVal: &'a Value, ToType: &'a Type) -> &'a Value; + pub fn LLVMConstIntCast(ConstantVal: &'a Value, ToType: &'a Type, isSigned: Bool) -> &'a Value; + pub fn LLVMConstFPCast(ConstantVal: &'a Value, ToType: &'a Type) -> &'a Value; + pub fn LLVMConstExtractValue(AggConstant: &Value, IdxList: *const c_uint, NumIdx: c_uint) - -> ValueRef; + -> &Value; pub fn LLVMConstInlineAsm(Ty: &Type, AsmString: *const c_char, Constraints: *const c_char, HasSideEffects: Bool, IsAlignStack: Bool) - -> ValueRef; + -> &Value; // Operations on global variables, functions, and aliases (globals) - 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); + pub fn LLVMIsDeclaration(Global: &Value) -> Bool; + pub fn LLVMRustGetLinkage(Global: &Value) -> Linkage; + pub fn LLVMRustSetLinkage(Global: &Value, RustLinkage: Linkage); + pub fn LLVMGetSection(Global: &Value) -> *const c_char; + pub fn LLVMSetSection(Global: &Value, Section: *const c_char); + pub fn LLVMRustGetVisibility(Global: &Value) -> Visibility; + pub fn LLVMRustSetVisibility(Global: &Value, Viz: Visibility); + pub fn LLVMGetAlignment(Global: &Value) -> c_uint; + pub fn LLVMSetAlignment(Global: &Value, Bytes: c_uint); + pub fn LLVMSetDLLStorageClass(V: &Value, C: DLLStorageClass); // Operations on global variables - pub fn LLVMIsAGlobalVariable(GlobalVar: ValueRef) -> ValueRef; - pub fn LLVMAddGlobal(M: &Module, Ty: &Type, Name: *const c_char) -> ValueRef; - pub fn LLVMGetNamedGlobal(M: &Module, Name: *const c_char) -> ValueRef; - pub fn LLVMRustGetOrInsertGlobal(M: &Module, Name: *const c_char, T: &Type) -> ValueRef; - pub fn LLVMGetFirstGlobal(M: &Module) -> 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: &Module, Name: *const c_char) -> ValueRef; - pub fn LLVMSetTailCall(CallInst: ValueRef, IsTailCall: Bool); + pub fn LLVMIsAGlobalVariable(GlobalVar: &Value) -> Option<&Value>; + pub fn LLVMAddGlobal(M: &'a Module, Ty: &'a Type, Name: *const c_char) -> &'a Value; + pub fn LLVMGetNamedGlobal(M: &Module, Name: *const c_char) -> Option<&Value>; + pub fn LLVMRustGetOrInsertGlobal(M: &'a Module, Name: *const c_char, T: &'a Type) -> &'a Value; + pub fn LLVMGetFirstGlobal(M: &Module) -> Option<&Value>; + pub fn LLVMGetNextGlobal(GlobalVar: &Value) -> Option<&Value>; + pub fn LLVMDeleteGlobal(GlobalVar: &Value); + pub fn LLVMGetInitializer(GlobalVar: &Value) -> Option<&Value>; + pub fn LLVMSetInitializer(GlobalVar: &'a Value, ConstantVal: &'a Value); + pub fn LLVMSetThreadLocal(GlobalVar: &Value, IsThreadLocal: Bool); + pub fn LLVMSetThreadLocalMode(GlobalVar: &Value, Mode: ThreadLocalMode); + pub fn LLVMIsGlobalConstant(GlobalVar: &Value) -> Bool; + pub fn LLVMSetGlobalConstant(GlobalVar: &Value, IsConstant: Bool); + pub fn LLVMRustGetNamedValue(M: &Module, Name: *const c_char) -> Option<&Value>; + pub fn LLVMSetTailCall(CallInst: &Value, IsTailCall: Bool); // Operations on functions - pub fn LLVMAddFunction(M: &Module, Name: *const c_char, FunctionTy: &Type) -> ValueRef; - pub fn LLVMGetNamedFunction(M: &Module, Name: *const c_char) -> ValueRef; - pub fn LLVMGetFirstFunction(M: &Module) -> ValueRef; - pub fn LLVMGetNextFunction(Fn: ValueRef) -> ValueRef; - pub fn LLVMRustGetOrInsertFunction(M: &Module, + pub fn LLVMAddFunction(M: &'a Module, Name: *const c_char, FunctionTy: &'a Type) -> &'a Value; + pub fn LLVMGetNamedFunction(M: &Module, Name: *const c_char) -> &Value; + pub fn LLVMGetFirstFunction(M: &Module) -> &Value; + pub fn LLVMGetNextFunction(Fn: &Value) -> &Value; + pub fn LLVMRustGetOrInsertFunction(M: &'a Module, Name: *const c_char, - FunctionTy: &Type) - -> 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, + FunctionTy: &'a Type) + -> &'a Value; + pub fn LLVMSetFunctionCallConv(Fn: &Value, CC: c_uint); + pub fn LLVMRustAddAlignmentAttr(Fn: &Value, index: c_uint, bytes: u32); + pub fn LLVMRustAddDereferenceableAttr(Fn: &Value, index: c_uint, bytes: u64); + pub fn LLVMRustAddDereferenceableOrNullAttr(Fn: &Value, index: c_uint, bytes: u64); + pub fn LLVMRustAddFunctionAttribute(Fn: &Value, index: c_uint, attr: Attribute); + pub fn LLVMRustAddFunctionAttrStringValue(Fn: &Value, index: c_uint, Name: *const c_char, Value: *const c_char); - pub fn LLVMRustRemoveFunctionAttributes(Fn: ValueRef, index: c_uint, attr: Attribute); + pub fn LLVMRustRemoveFunctionAttributes(Fn: &Value, index: c_uint, attr: Attribute); // Operations on parameters - pub fn LLVMCountParams(Fn: ValueRef) -> c_uint; - pub fn LLVMGetParam(Fn: ValueRef, Index: c_uint) -> ValueRef; + pub fn LLVMCountParams(Fn: &Value) -> c_uint; + pub fn LLVMGetParam(Fn: &Value, Index: c_uint) -> &Value; // Operations on basic blocks - pub fn LLVMBasicBlockAsValue(BB: BasicBlockRef) -> ValueRef; - pub fn LLVMGetBasicBlockParent(BB: BasicBlockRef) -> ValueRef; - pub fn LLVMAppendBasicBlockInContext(C: &Context, - Fn: ValueRef, + pub fn LLVMBasicBlockAsValue(BB: BasicBlockRef) -> &'a Value; + pub fn LLVMGetBasicBlockParent(BB: BasicBlockRef) -> &'a Value; + pub fn LLVMAppendBasicBlockInContext(C: &'a Context, + Fn: &'a Value, 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); + pub fn LLVMGetInstructionParent(Inst: &Value) -> BasicBlockRef; + pub fn LLVMGetFirstBasicBlock(Fn: &Value) -> BasicBlockRef; + pub fn LLVMGetFirstInstruction(BB: BasicBlockRef) -> &'a Value; + pub fn LLVMInstructionEraseFromParent(Inst: &Value); // 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, + pub fn LLVMSetInstructionCallConv(Instr: &Value, CC: c_uint); + pub fn LLVMRustAddCallSiteAttribute(Instr: &Value, index: c_uint, attr: Attribute); + pub fn LLVMRustAddAlignmentCallSiteAttr(Instr: &Value, index: c_uint, bytes: u32); + pub fn LLVMRustAddDereferenceableCallSiteAttr(Instr: &Value, index: c_uint, bytes: u64); + pub fn LLVMRustAddDereferenceableOrNullCallSiteAttr(Instr: &Value, index: c_uint, bytes: u64); // Operations on load/store instructions (only) - pub fn LLVMSetVolatile(MemoryAccessInst: ValueRef, volatile: Bool); + pub fn LLVMSetVolatile(MemoryAccessInst: &Value, volatile: Bool); // Operations on phi nodes - pub fn LLVMAddIncoming(PhiNode: ValueRef, - IncomingValues: *const ValueRef, + pub fn LLVMAddIncoming(PhiNode: &'a Value, + IncomingValues: *const &'a Value, IncomingBlocks: *const BasicBlockRef, Count: c_uint); // Instruction builders pub fn LLVMCreateBuilderInContext(C: &Context) -> &Builder; - pub fn LLVMPositionBuilder(Builder: &Builder, Block: BasicBlockRef, Instr: ValueRef); - pub fn LLVMPositionBuilderBefore(Builder: &Builder, Instr: ValueRef); + pub fn LLVMPositionBuilder(Builder: &'a Builder, Block: BasicBlockRef, Instr: &'a Value); + pub fn LLVMPositionBuilderBefore(Builder: &'a Builder, Instr: &'a Value); pub fn LLVMPositionBuilderAtEnd(Builder: &Builder, Block: BasicBlockRef); pub fn LLVMGetInsertBlock(Builder: &Builder) -> BasicBlockRef; pub fn LLVMDisposeBuilder(Builder: &Builder); // Metadata - pub fn LLVMSetCurrentDebugLocation(Builder: &Builder, L: Option>); - pub fn LLVMGetCurrentDebugLocation(Builder: &Builder) -> ValueRef; - pub fn LLVMSetInstDebugLocation(Builder: &Builder, Inst: ValueRef); + pub fn LLVMSetCurrentDebugLocation(Builder: &'a Builder, L: Option<&'a Value>); + pub fn LLVMGetCurrentDebugLocation(Builder: &Builder) -> &Value; + pub fn LLVMSetInstDebugLocation(Builder: &'a Builder, Inst: &'a Value); // Terminators - pub fn LLVMBuildRetVoid(B: &Builder) -> ValueRef; - pub fn LLVMBuildRet(B: &Builder, V: ValueRef) -> ValueRef; - pub fn LLVMBuildAggregateRet(B: &Builder, RetVals: *const ValueRef, N: c_uint) -> ValueRef; - pub fn LLVMBuildBr(B: &Builder, Dest: BasicBlockRef) -> ValueRef; - pub fn LLVMBuildCondBr(B: &Builder, - If: ValueRef, + pub fn LLVMBuildRetVoid(B: &Builder) -> &Value; + pub fn LLVMBuildRet(B: &'a Builder, V: &'a Value) -> &'a Value; + pub fn LLVMBuildAggregateRet(B: &'a Builder, RetVals: *const &'a Value, N: c_uint) -> &'a Value; + pub fn LLVMBuildBr(B: &Builder, Dest: BasicBlockRef) -> &Value; + pub fn LLVMBuildCondBr(B: &'a Builder, + If: &'a Value, Then: BasicBlockRef, Else: BasicBlockRef) - -> ValueRef; - pub fn LLVMBuildSwitch(B: &Builder, - V: ValueRef, + -> &'a Value; + pub fn LLVMBuildSwitch(B: &'a Builder, + V: &'a Value, Else: BasicBlockRef, NumCases: c_uint) - -> ValueRef; - pub fn LLVMBuildIndirectBr(B: &Builder, Addr: ValueRef, NumDests: c_uint) -> ValueRef; - pub fn LLVMRustBuildInvoke(B: &Builder, - Fn: ValueRef, - Args: *const ValueRef, + -> &'a Value; + pub fn LLVMBuildIndirectBr(B: &'a Builder, Addr: &'a Value, NumDests: c_uint) -> &'a Value; + pub fn LLVMRustBuildInvoke(B: &'a Builder, + Fn: &'a Value, + Args: *const &'a Value, NumArgs: c_uint, Then: BasicBlockRef, Catch: BasicBlockRef, Bundle: Option>, Name: *const c_char) - -> ValueRef; + -> &'a Value; pub fn LLVMBuildLandingPad(B: &'a Builder, Ty: &'a Type, - PersFn: ValueRef, + PersFn: &'a Value, NumClauses: c_uint, Name: *const c_char) - -> ValueRef; - pub fn LLVMBuildResume(B: &Builder, Exn: ValueRef) -> ValueRef; - pub fn LLVMBuildUnreachable(B: &Builder) -> ValueRef; + -> &'a Value; + pub fn LLVMBuildResume(B: &'a Builder, Exn: &'a Value) -> &'a Value; + pub fn LLVMBuildUnreachable(B: &Builder) -> &Value; - pub fn LLVMRustBuildCleanupPad(B: &Builder, - ParentPad: Option>, + pub fn LLVMRustBuildCleanupPad(B: &'a Builder, + ParentPad: Option<&'a Value>, ArgCnt: c_uint, - Args: *const ValueRef, + Args: *const &'a Value, Name: *const c_char) - -> ValueRef; - pub fn LLVMRustBuildCleanupRet(B: &Builder, - CleanupPad: ValueRef, + -> Option<&'a Value>; + pub fn LLVMRustBuildCleanupRet(B: &'a Builder, + CleanupPad: &'a Value, UnwindBB: Option>) - -> ValueRef; - pub fn LLVMRustBuildCatchPad(B: &Builder, - ParentPad: ValueRef, + -> Option<&'a Value>; + pub fn LLVMRustBuildCatchPad(B: &'a Builder, + ParentPad: &'a Value, ArgCnt: c_uint, - Args: *const ValueRef, + Args: *const &'a Value, Name: *const c_char) - -> ValueRef; - pub fn LLVMRustBuildCatchRet(B: &Builder, Pad: ValueRef, BB: BasicBlockRef) -> ValueRef; - pub fn LLVMRustBuildCatchSwitch(Builder: &Builder, - ParentPad: Option>, + -> Option<&'a Value>; + pub fn LLVMRustBuildCatchRet(B: &'a Builder, Pad: &'a Value, BB: BasicBlockRef) -> Option<&'a Value>; + pub fn LLVMRustBuildCatchSwitch(Builder: &'a Builder, + ParentPad: Option<&'a Value>, BB: Option>, NumHandlers: c_uint, Name: *const c_char) - -> ValueRef; - pub fn LLVMRustAddHandler(CatchSwitch: ValueRef, Handler: BasicBlockRef); - pub fn LLVMSetPersonalityFn(Func: ValueRef, Pers: ValueRef); + -> Option<&'a Value>; + pub fn LLVMRustAddHandler(CatchSwitch: &Value, Handler: BasicBlockRef); + pub fn LLVMSetPersonalityFn(Func: &'a Value, Pers: &'a Value); // Add a case to the switch instruction - pub fn LLVMAddCase(Switch: ValueRef, OnVal: ValueRef, Dest: BasicBlockRef); + pub fn LLVMAddCase(Switch: &'a Value, OnVal: &'a Value, Dest: BasicBlockRef); // Add a clause to the landing pad instruction - pub fn LLVMAddClause(LandingPad: ValueRef, ClauseVal: ValueRef); + pub fn LLVMAddClause(LandingPad: &'a Value, ClauseVal: &'a Value); // Set the cleanup on a landing pad instruction - pub fn LLVMSetCleanup(LandingPad: ValueRef, Val: Bool); + pub fn LLVMSetCleanup(LandingPad: &Value, Val: Bool); // Arithmetic - pub fn LLVMBuildAdd(B: &Builder, - LHS: ValueRef, - RHS: ValueRef, + pub fn LLVMBuildAdd(B: &'a Builder, + LHS: &'a Value, + RHS: &'a Value, Name: *const c_char) - -> ValueRef; - pub fn LLVMBuildNSWAdd(B: &Builder, - LHS: ValueRef, - RHS: ValueRef, + -> &'a Value; + pub fn LLVMBuildNSWAdd(B: &'a Builder, + LHS: &'a Value, + RHS: &'a Value, Name: *const c_char) - -> ValueRef; - pub fn LLVMBuildNUWAdd(B: &Builder, - LHS: ValueRef, - RHS: ValueRef, + -> &'a Value; + pub fn LLVMBuildNUWAdd(B: &'a Builder, + LHS: &'a Value, + RHS: &'a Value, Name: *const c_char) - -> ValueRef; - pub fn LLVMBuildFAdd(B: &Builder, - LHS: ValueRef, - RHS: ValueRef, + -> &'a Value; + pub fn LLVMBuildFAdd(B: &'a Builder, + LHS: &'a Value, + RHS: &'a Value, Name: *const c_char) - -> ValueRef; - pub fn LLVMBuildSub(B: &Builder, - LHS: ValueRef, - RHS: ValueRef, + -> &'a Value; + pub fn LLVMBuildSub(B: &'a Builder, + LHS: &'a Value, + RHS: &'a Value, Name: *const c_char) - -> ValueRef; - pub fn LLVMBuildNSWSub(B: &Builder, - LHS: ValueRef, - RHS: ValueRef, + -> &'a Value; + pub fn LLVMBuildNSWSub(B: &'a Builder, + LHS: &'a Value, + RHS: &'a Value, Name: *const c_char) - -> ValueRef; - pub fn LLVMBuildNUWSub(B: &Builder, - LHS: ValueRef, - RHS: ValueRef, + -> &'a Value; + pub fn LLVMBuildNUWSub(B: &'a Builder, + LHS: &'a Value, + RHS: &'a Value, Name: *const c_char) - -> ValueRef; - pub fn LLVMBuildFSub(B: &Builder, - LHS: ValueRef, - RHS: ValueRef, + -> &'a Value; + pub fn LLVMBuildFSub(B: &'a Builder, + LHS: &'a Value, + RHS: &'a Value, Name: *const c_char) - -> ValueRef; - pub fn LLVMBuildMul(B: &Builder, - LHS: ValueRef, - RHS: ValueRef, + -> &'a Value; + pub fn LLVMBuildMul(B: &'a Builder, + LHS: &'a Value, + RHS: &'a Value, Name: *const c_char) - -> ValueRef; - pub fn LLVMBuildNSWMul(B: &Builder, - LHS: ValueRef, - RHS: ValueRef, + -> &'a Value; + pub fn LLVMBuildNSWMul(B: &'a Builder, + LHS: &'a Value, + RHS: &'a Value, Name: *const c_char) - -> ValueRef; - pub fn LLVMBuildNUWMul(B: &Builder, - LHS: ValueRef, - RHS: ValueRef, + -> &'a Value; + pub fn LLVMBuildNUWMul(B: &'a Builder, + LHS: &'a Value, + RHS: &'a Value, Name: *const c_char) - -> ValueRef; - pub fn LLVMBuildFMul(B: &Builder, - LHS: ValueRef, - RHS: ValueRef, + -> &'a Value; + pub fn LLVMBuildFMul(B: &'a Builder, + LHS: &'a Value, + RHS: &'a Value, Name: *const c_char) - -> ValueRef; - pub fn LLVMBuildUDiv(B: &Builder, - LHS: ValueRef, - RHS: ValueRef, + -> &'a Value; + pub fn LLVMBuildUDiv(B: &'a Builder, + LHS: &'a Value, + RHS: &'a Value, Name: *const c_char) - -> ValueRef; - pub fn LLVMBuildExactUDiv(B: &Builder, - LHS: ValueRef, - RHS: ValueRef, + -> &'a Value; + pub fn LLVMBuildExactUDiv(B: &'a Builder, + LHS: &'a Value, + RHS: &'a Value, Name: *const c_char) - -> ValueRef; - pub fn LLVMBuildSDiv(B: &Builder, - LHS: ValueRef, - RHS: ValueRef, + -> &'a Value; + pub fn LLVMBuildSDiv(B: &'a Builder, + LHS: &'a Value, + RHS: &'a Value, Name: *const c_char) - -> ValueRef; - pub fn LLVMBuildExactSDiv(B: &Builder, - LHS: ValueRef, - RHS: ValueRef, + -> &'a Value; + pub fn LLVMBuildExactSDiv(B: &'a Builder, + LHS: &'a Value, + RHS: &'a Value, Name: *const c_char) - -> ValueRef; - pub fn LLVMBuildFDiv(B: &Builder, - LHS: ValueRef, - RHS: ValueRef, + -> &'a Value; + pub fn LLVMBuildFDiv(B: &'a Builder, + LHS: &'a Value, + RHS: &'a Value, Name: *const c_char) - -> ValueRef; - pub fn LLVMBuildURem(B: &Builder, - LHS: ValueRef, - RHS: ValueRef, + -> &'a Value; + pub fn LLVMBuildURem(B: &'a Builder, + LHS: &'a Value, + RHS: &'a Value, Name: *const c_char) - -> ValueRef; - pub fn LLVMBuildSRem(B: &Builder, - LHS: ValueRef, - RHS: ValueRef, + -> &'a Value; + pub fn LLVMBuildSRem(B: &'a Builder, + LHS: &'a Value, + RHS: &'a Value, Name: *const c_char) - -> ValueRef; - pub fn LLVMBuildFRem(B: &Builder, - LHS: ValueRef, - RHS: ValueRef, + -> &'a Value; + pub fn LLVMBuildFRem(B: &'a Builder, + LHS: &'a Value, + RHS: &'a Value, Name: *const c_char) - -> ValueRef; - pub fn LLVMBuildShl(B: &Builder, - LHS: ValueRef, - RHS: ValueRef, + -> &'a Value; + pub fn LLVMBuildShl(B: &'a Builder, + LHS: &'a Value, + RHS: &'a Value, Name: *const c_char) - -> ValueRef; - pub fn LLVMBuildLShr(B: &Builder, - LHS: ValueRef, - RHS: ValueRef, + -> &'a Value; + pub fn LLVMBuildLShr(B: &'a Builder, + LHS: &'a Value, + RHS: &'a Value, Name: *const c_char) - -> ValueRef; - pub fn LLVMBuildAShr(B: &Builder, - LHS: ValueRef, - RHS: ValueRef, + -> &'a Value; + pub fn LLVMBuildAShr(B: &'a Builder, + LHS: &'a Value, + RHS: &'a Value, Name: *const c_char) - -> ValueRef; - pub fn LLVMBuildAnd(B: &Builder, - LHS: ValueRef, - RHS: ValueRef, + -> &'a Value; + pub fn LLVMBuildAnd(B: &'a Builder, + LHS: &'a Value, + RHS: &'a Value, Name: *const c_char) - -> ValueRef; - pub fn LLVMBuildOr(B: &Builder, - LHS: ValueRef, - RHS: ValueRef, + -> &'a Value; + pub fn LLVMBuildOr(B: &'a Builder, + LHS: &'a Value, + RHS: &'a Value, Name: *const c_char) - -> ValueRef; - pub fn LLVMBuildXor(B: &Builder, - LHS: ValueRef, - RHS: ValueRef, + -> &'a Value; + pub fn LLVMBuildXor(B: &'a Builder, + LHS: &'a Value, + RHS: &'a Value, Name: *const c_char) - -> ValueRef; - pub fn LLVMBuildBinOp(B: &Builder, + -> &'a Value; + pub fn LLVMBuildBinOp(B: &'a Builder, Op: Opcode, - LHS: ValueRef, - RHS: ValueRef, + LHS: &'a Value, + RHS: &'a Value, Name: *const c_char) - -> ValueRef; - pub fn LLVMBuildNeg(B: &Builder, V: ValueRef, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildNSWNeg(B: &Builder, V: ValueRef, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildNUWNeg(B: &Builder, V: ValueRef, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildFNeg(B: &Builder, V: ValueRef, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildNot(B: &Builder, V: ValueRef, Name: *const c_char) -> ValueRef; - pub fn LLVMRustSetHasUnsafeAlgebra(Instr: ValueRef); + -> &'a Value; + pub fn LLVMBuildNeg(B: &'a Builder, V: &'a Value, Name: *const c_char) -> &'a Value; + pub fn LLVMBuildNSWNeg(B: &'a Builder, V: &'a Value, Name: *const c_char) -> &'a Value; + pub fn LLVMBuildNUWNeg(B: &'a Builder, V: &'a Value, Name: *const c_char) -> &'a Value; + pub fn LLVMBuildFNeg(B: &'a Builder, V: &'a Value, Name: *const c_char) -> &'a Value; + pub fn LLVMBuildNot(B: &'a Builder, V: &'a Value, Name: *const c_char) -> &'a Value; + pub fn LLVMRustSetHasUnsafeAlgebra(Instr: &Value); // Memory - pub fn LLVMBuildAlloca(B: &Builder, Ty: &Type, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildFree(B: &Builder, PointerVal: ValueRef) -> ValueRef; - pub fn LLVMBuildLoad(B: &Builder, PointerVal: ValueRef, Name: *const c_char) -> ValueRef; + pub fn LLVMBuildAlloca(B: &'a Builder, Ty: &'a Type, Name: *const c_char) -> &'a Value; + pub fn LLVMBuildFree(B: &'a Builder, PointerVal: &'a Value) -> &'a Value; + pub fn LLVMBuildLoad(B: &'a Builder, PointerVal: &'a Value, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildStore(B: &Builder, Val: ValueRef, Ptr: ValueRef) -> ValueRef; + pub fn LLVMBuildStore(B: &'a Builder, Val: &'a Value, Ptr: &'a Value) -> &'a Value; - pub fn LLVMBuildGEP(B: &Builder, - Pointer: ValueRef, - Indices: *const ValueRef, + pub fn LLVMBuildGEP(B: &'a Builder, + Pointer: &'a Value, + Indices: *const &'a Value, NumIndices: c_uint, Name: *const c_char) - -> ValueRef; - pub fn LLVMBuildInBoundsGEP(B: &Builder, - Pointer: ValueRef, - Indices: *const ValueRef, + -> &'a Value; + pub fn LLVMBuildInBoundsGEP(B: &'a Builder, + Pointer: &'a Value, + Indices: *const &'a Value, NumIndices: c_uint, Name: *const c_char) - -> ValueRef; - pub fn LLVMBuildStructGEP(B: &Builder, - Pointer: ValueRef, + -> &'a Value; + pub fn LLVMBuildStructGEP(B: &'a Builder, + Pointer: &'a Value, Idx: c_uint, Name: *const c_char) - -> ValueRef; + -> &'a Value; pub fn LLVMBuildGlobalString(B: &Builder, Str: *const c_char, Name: *const c_char) - -> ValueRef; + -> &Value; pub fn LLVMBuildGlobalStringPtr(B: &Builder, Str: *const c_char, Name: *const c_char) - -> ValueRef; + -> &Value; // Casts pub fn LLVMBuildTrunc(B: &'a Builder, - Val: ValueRef, + Val: &'a Value, DestTy: &'a Type, Name: *const c_char) - -> ValueRef; + -> &'a Value; pub fn LLVMBuildZExt(B: &'a Builder, - Val: ValueRef, + Val: &'a Value, DestTy: &'a Type, Name: *const c_char) - -> ValueRef; + -> &'a Value; pub fn LLVMBuildSExt(B: &'a Builder, - Val: ValueRef, + Val: &'a Value, DestTy: &'a Type, Name: *const c_char) - -> ValueRef; + -> &'a Value; pub fn LLVMBuildFPToUI(B: &'a Builder, - Val: ValueRef, + Val: &'a Value, DestTy: &'a Type, Name: *const c_char) - -> ValueRef; + -> &'a Value; pub fn LLVMBuildFPToSI(B: &'a Builder, - Val: ValueRef, + Val: &'a Value, DestTy: &'a Type, Name: *const c_char) - -> ValueRef; + -> &'a Value; pub fn LLVMBuildUIToFP(B: &'a Builder, - Val: ValueRef, + Val: &'a Value, DestTy: &'a Type, Name: *const c_char) - -> ValueRef; + -> &'a Value; pub fn LLVMBuildSIToFP(B: &'a Builder, - Val: ValueRef, + Val: &'a Value, DestTy: &'a Type, Name: *const c_char) - -> ValueRef; + -> &'a Value; pub fn LLVMBuildFPTrunc(B: &'a Builder, - Val: ValueRef, + Val: &'a Value, DestTy: &'a Type, Name: *const c_char) - -> ValueRef; + -> &'a Value; pub fn LLVMBuildFPExt(B: &'a Builder, - Val: ValueRef, + Val: &'a Value, DestTy: &'a Type, Name: *const c_char) - -> ValueRef; + -> &'a Value; pub fn LLVMBuildPtrToInt(B: &'a Builder, - Val: ValueRef, + Val: &'a Value, DestTy: &'a Type, Name: *const c_char) - -> ValueRef; + -> &'a Value; pub fn LLVMBuildIntToPtr(B: &'a Builder, - Val: ValueRef, + Val: &'a Value, DestTy: &'a Type, Name: *const c_char) - -> ValueRef; + -> &'a Value; pub fn LLVMBuildBitCast(B: &'a Builder, - Val: ValueRef, + Val: &'a Value, DestTy: &'a Type, Name: *const c_char) - -> ValueRef; + -> &'a Value; pub fn LLVMBuildZExtOrBitCast(B: &'a Builder, - Val: ValueRef, + Val: &'a Value, DestTy: &'a Type, Name: *const c_char) - -> ValueRef; + -> &'a Value; pub fn LLVMBuildSExtOrBitCast(B: &'a Builder, - Val: ValueRef, + Val: &'a Value, DestTy: &'a Type, Name: *const c_char) - -> ValueRef; + -> &'a Value; pub fn LLVMBuildTruncOrBitCast(B: &'a Builder, - Val: ValueRef, + Val: &'a Value, DestTy: &'a Type, Name: *const c_char) - -> ValueRef; + -> &'a Value; pub fn LLVMBuildCast(B: &'a Builder, Op: Opcode, - Val: ValueRef, + Val: &'a Value, DestTy: &'a Type, Name: *const c_char) - -> ValueRef; + -> &'a Value; pub fn LLVMBuildPointerCast(B: &'a Builder, - Val: ValueRef, + Val: &'a Value, DestTy: &'a Type, Name: *const c_char) - -> ValueRef; + -> &'a Value; pub fn LLVMRustBuildIntCast(B: &'a Builder, - Val: ValueRef, + Val: &'a Value, DestTy: &'a Type, IsSized: bool) - -> ValueRef; + -> &'a Value; pub fn LLVMBuildFPCast(B: &'a Builder, - Val: ValueRef, + Val: &'a Value, DestTy: &'a Type, Name: *const c_char) - -> ValueRef; + -> &'a Value; // Comparisons - pub fn LLVMBuildICmp(B: &Builder, + pub fn LLVMBuildICmp(B: &'a Builder, Op: c_uint, - LHS: ValueRef, - RHS: ValueRef, + LHS: &'a Value, + RHS: &'a Value, Name: *const c_char) - -> ValueRef; - pub fn LLVMBuildFCmp(B: &Builder, + -> &'a Value; + pub fn LLVMBuildFCmp(B: &'a Builder, Op: c_uint, - LHS: ValueRef, - RHS: ValueRef, + LHS: &'a Value, + RHS: &'a Value, Name: *const c_char) - -> ValueRef; + -> &'a Value; // Miscellaneous instructions - pub fn LLVMBuildPhi(B: &Builder, Ty: &Type, Name: *const c_char) -> ValueRef; - pub fn LLVMRustBuildCall(B: &Builder, - Fn: ValueRef, - Args: *const ValueRef, + pub fn LLVMBuildPhi(B: &'a Builder, Ty: &'a Type, Name: *const c_char) -> &'a Value; + pub fn LLVMRustBuildCall(B: &'a Builder, + Fn: &'a Value, + Args: *const &'a Value, NumArgs: c_uint, Bundle: Option>, Name: *const c_char) - -> ValueRef; - pub fn LLVMBuildSelect(B: &Builder, - If: ValueRef, - Then: ValueRef, - Else: ValueRef, + -> &'a Value; + pub fn LLVMBuildSelect(B: &'a Builder, + If: &'a Value, + Then: &'a Value, + Else: &'a Value, Name: *const c_char) - -> ValueRef; + -> &'a Value; pub fn LLVMBuildVAArg(B: &'a Builder, - list: ValueRef, + list: &'a Value, Ty: &'a Type, Name: *const c_char) - -> ValueRef; - pub fn LLVMBuildExtractElement(B: &Builder, - VecVal: ValueRef, - Index: ValueRef, + -> &'a Value; + pub fn LLVMBuildExtractElement(B: &'a Builder, + VecVal: &'a Value, + Index: &'a Value, Name: *const c_char) - -> ValueRef; - pub fn LLVMBuildInsertElement(B: &Builder, - VecVal: ValueRef, - EltVal: ValueRef, - Index: ValueRef, + -> &'a Value; + pub fn LLVMBuildInsertElement(B: &'a Builder, + VecVal: &'a Value, + EltVal: &'a Value, + Index: &'a Value, Name: *const c_char) - -> ValueRef; - pub fn LLVMBuildShuffleVector(B: &Builder, - V1: ValueRef, - V2: ValueRef, - Mask: ValueRef, + -> &'a Value; + pub fn LLVMBuildShuffleVector(B: &'a Builder, + V1: &'a Value, + V2: &'a Value, + Mask: &'a Value, Name: *const c_char) - -> ValueRef; - pub fn LLVMBuildExtractValue(B: &Builder, - AggVal: ValueRef, + -> &'a Value; + pub fn LLVMBuildExtractValue(B: &'a Builder, + AggVal: &'a Value, Index: c_uint, Name: *const c_char) - -> ValueRef; - pub fn LLVMBuildInsertValue(B: &Builder, - AggVal: ValueRef, - EltVal: ValueRef, + -> &'a Value; + pub fn LLVMBuildInsertValue(B: &'a Builder, + AggVal: &'a Value, + EltVal: &'a Value, Index: c_uint, Name: *const c_char) - -> ValueRef; - - pub fn LLVMRustBuildVectorReduceFAdd(B: &Builder, - Acc: ValueRef, - Src: ValueRef) - -> ValueRef; - pub fn LLVMRustBuildVectorReduceFMul(B: &Builder, - Acc: ValueRef, - Src: ValueRef) - -> ValueRef; - pub fn LLVMRustBuildVectorReduceAdd(B: &Builder, - Src: ValueRef) - -> ValueRef; - pub fn LLVMRustBuildVectorReduceMul(B: &Builder, - Src: ValueRef) - -> ValueRef; - pub fn LLVMRustBuildVectorReduceAnd(B: &Builder, - Src: ValueRef) - -> ValueRef; - pub fn LLVMRustBuildVectorReduceOr(B: &Builder, - Src: ValueRef) - -> ValueRef; - pub fn LLVMRustBuildVectorReduceXor(B: &Builder, - Src: ValueRef) - -> ValueRef; - pub fn LLVMRustBuildVectorReduceMin(B: &Builder, - Src: ValueRef, + -> &'a Value; + + pub fn LLVMRustBuildVectorReduceFAdd(B: &'a Builder, + Acc: &'a Value, + Src: &'a Value) + -> Option<&'a Value>; + pub fn LLVMRustBuildVectorReduceFMul(B: &'a Builder, + Acc: &'a Value, + Src: &'a Value) + -> Option<&'a Value>; + pub fn LLVMRustBuildVectorReduceAdd(B: &'a Builder, + Src: &'a Value) + -> Option<&'a Value>; + pub fn LLVMRustBuildVectorReduceMul(B: &'a Builder, + Src: &'a Value) + -> Option<&'a Value>; + pub fn LLVMRustBuildVectorReduceAnd(B: &'a Builder, + Src: &'a Value) + -> Option<&'a Value>; + pub fn LLVMRustBuildVectorReduceOr(B: &'a Builder, + Src: &'a Value) + -> Option<&'a Value>; + pub fn LLVMRustBuildVectorReduceXor(B: &'a Builder, + Src: &'a Value) + -> Option<&'a Value>; + pub fn LLVMRustBuildVectorReduceMin(B: &'a Builder, + Src: &'a Value, IsSigned: bool) - -> ValueRef; - pub fn LLVMRustBuildVectorReduceMax(B: &Builder, - Src: ValueRef, + -> Option<&'a Value>; + pub fn LLVMRustBuildVectorReduceMax(B: &'a Builder, + Src: &'a Value, IsSigned: bool) - -> ValueRef; - pub fn LLVMRustBuildVectorReduceFMin(B: &Builder, - Src: ValueRef, + -> Option<&'a Value>; + pub fn LLVMRustBuildVectorReduceFMin(B: &'a Builder, + Src: &'a Value, IsNaN: bool) - -> ValueRef; - pub fn LLVMRustBuildVectorReduceFMax(B: &Builder, - Src: ValueRef, + -> Option<&'a Value>; + pub fn LLVMRustBuildVectorReduceFMax(B: &'a Builder, + Src: &'a Value, IsNaN: bool) - -> ValueRef; + -> Option<&'a Value>; - pub fn LLVMRustBuildMinNum(B: &Builder, LHS: ValueRef, LHS: ValueRef) -> ValueRef; - pub fn LLVMRustBuildMaxNum(B: &Builder, LHS: ValueRef, LHS: ValueRef) -> ValueRef; + pub fn LLVMRustBuildMinNum(B: &'a Builder, LHS: &'a Value, LHS: &'a Value) -> Option<&'a Value>; + pub fn LLVMRustBuildMaxNum(B: &'a Builder, LHS: &'a Value, LHS: &'a Value) -> Option<&'a Value>; - pub fn LLVMBuildIsNull(B: &Builder, Val: ValueRef, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildIsNotNull(B: &Builder, Val: ValueRef, Name: *const c_char) -> ValueRef; - pub fn LLVMBuildPtrDiff(B: &Builder, - LHS: ValueRef, - RHS: ValueRef, + pub fn LLVMBuildIsNull(B: &'a Builder, Val: &'a Value, Name: *const c_char) -> &'a Value; + pub fn LLVMBuildIsNotNull(B: &'a Builder, Val: &'a Value, Name: *const c_char) -> &'a Value; + pub fn LLVMBuildPtrDiff(B: &'a Builder, + LHS: &'a Value, + RHS: &'a Value, Name: *const c_char) - -> ValueRef; + -> &'a Value; // Atomic Operations - pub fn LLVMRustBuildAtomicLoad(B: &Builder, - PointerVal: ValueRef, + pub fn LLVMRustBuildAtomicLoad(B: &'a Builder, + PointerVal: &'a Value, Name: *const c_char, Order: AtomicOrdering) - -> ValueRef; + -> &'a Value; - pub fn LLVMRustBuildAtomicStore(B: &Builder, - Val: ValueRef, - Ptr: ValueRef, + pub fn LLVMRustBuildAtomicStore(B: &'a Builder, + Val: &'a Value, + Ptr: &'a Value, Order: AtomicOrdering) - -> ValueRef; + -> &'a Value; - pub fn LLVMRustBuildAtomicCmpXchg(B: &Builder, - LHS: ValueRef, - CMP: ValueRef, - RHS: ValueRef, + pub fn LLVMRustBuildAtomicCmpXchg(B: &'a Builder, + LHS: &'a Value, + CMP: &'a Value, + RHS: &'a Value, Order: AtomicOrdering, FailureOrder: AtomicOrdering, Weak: Bool) - -> ValueRef; + -> &'a Value; - pub fn LLVMBuildAtomicRMW(B: &Builder, + pub fn LLVMBuildAtomicRMW(B: &'a Builder, Op: AtomicRmwBinOp, - LHS: ValueRef, - RHS: ValueRef, + LHS: &'a Value, + RHS: &'a Value, Order: AtomicOrdering, SingleThreaded: Bool) - -> ValueRef; + -> &'a Value; pub fn LLVMRustBuildAtomicFence(B: &Builder, Order: AtomicOrdering, @@ -1256,8 +1255,8 @@ extern "C" { // Selected entries from the downcasts. - pub fn LLVMIsATerminatorInst(Inst: ValueRef) -> ValueRef; - pub fn LLVMIsAStoreInst(Inst: ValueRef) -> ValueRef; + pub fn LLVMIsATerminatorInst(Inst: &Value) -> &Value; + pub fn LLVMIsAStoreInst(Inst: &Value) -> &Value; /// Writes a module to the specified path. Returns 0 on success. pub fn LLVMWriteBitcodeToFile(M: &Module, Path: *const c_char) -> c_int; @@ -1342,7 +1341,7 @@ extern "C" { SideEffects: Bool, AlignStack: Bool, Dialect: AsmDialect) - -> ValueRef; + -> &Value; pub fn LLVMRustDebugMetadataVersion() -> u32; pub fn LLVMRustVersionMajor() -> u32; @@ -1350,7 +1349,7 @@ extern "C" { pub fn LLVMRustAddModuleFlag(M: &Module, name: *const c_char, value: u32); - pub fn LLVMRustMetadataAsValue(C: &'a Context, MD: &'a Metadata) -> ValueRef; + pub fn LLVMRustMetadataAsValue(C: &'a Context, MD: &'a Metadata) -> &'a Value; pub fn LLVMRustDIBuilderCreate(M: &Module) -> &DIBuilder; @@ -1390,7 +1389,7 @@ extern "C" { ScopeLine: c_uint, Flags: DIFlags, isOptimized: bool, - Fn: ValueRef, + Fn: &'a Value, TParam: &'a DIArray, Decl: Option<&'a DIDescriptor>) -> &'a DISubprogram; @@ -1456,7 +1455,7 @@ extern "C" { LineNo: c_uint, Ty: &'a DIType, isLocalToUnit: bool, - Val: ValueRef, + Val: &'a Value, Decl: Option<&'a DIDescriptor>, AlignInBits: u32) -> &'a DIGlobalVariable; @@ -1499,13 +1498,13 @@ extern "C" { -> &'a DIArray; pub fn LLVMRustDIBuilderInsertDeclareAtEnd(Builder: &'a DIBuilder, - Val: ValueRef, + Val: &'a Value, VarInfo: &'a DIVariable, AddrOps: *const i64, AddrOpsCount: c_uint, - DL: ValueRef, + DL: &'a Value, InsertAtEnd: BasicBlockRef) - -> ValueRef; + -> &'a Value; pub fn LLVMRustDIBuilderCreateEnumerator(Builder: &DIBuilder, Name: *const c_char, @@ -1536,7 +1535,7 @@ extern "C" { UniqueId: *const c_char) -> &'a DIType; - pub fn LLVMSetUnnamedAddr(GlobalVar: ValueRef, UnnamedAddr: Bool); + pub fn LLVMSetUnnamedAddr(GlobalVar: &Value, UnnamedAddr: Bool); pub fn LLVMRustDIBuilderCreateTemplateTypeParameter(Builder: &'a DIBuilder, Scope: Option<&'a DIScope>, @@ -1565,15 +1564,15 @@ extern "C" { Column: c_uint, Scope: &'a DIScope, InlinedAt: Option<&'a Metadata>) - -> ValueRef; + -> &'a Value; pub fn LLVMRustDIBuilderCreateOpDeref() -> i64; pub fn LLVMRustDIBuilderCreateOpPlusUconst() -> i64; pub fn LLVMRustWriteTypeToString(Type: &Type, s: RustStringRef); - pub fn LLVMRustWriteValueToString(value_ref: ValueRef, s: RustStringRef); + pub fn LLVMRustWriteValueToString(value_ref: &Value, s: RustStringRef); - pub fn LLVMIsAConstantInt(value_ref: ValueRef) -> ValueRef; - pub fn LLVMIsAConstantFP(value_ref: ValueRef) -> ValueRef; + pub fn LLVMIsAConstantInt(value_ref: &Value) -> Option<&Value>; + pub fn LLVMIsAConstantFP(value_ref: &Value) -> Option<&Value>; pub fn LLVMRustPassKind(Pass: PassRef) -> PassKind; pub fn LLVMRustFindAndCreatePass(Pass: *const c_char) -> PassRef; @@ -1653,7 +1652,7 @@ extern "C" { pub fn LLVMRustUnpackOptimizationDiagnostic(DI: DiagnosticInfoRef, pass_name_out: RustStringRef, - function_out: *mut ValueRef, + function_out: *mut Option<&Value>, loc_line_out: *mut c_uint, loc_column_out: *mut c_uint, loc_filename_out: RustStringRef, @@ -1661,7 +1660,7 @@ extern "C" { pub fn LLVMRustUnpackInlineAsmDiagnostic(DI: DiagnosticInfoRef, cookie_out: *mut c_uint, message_out: *mut TwineRef, - instruction_out: *mut ValueRef); + instruction_out: *mut Option<&Value>); pub fn LLVMRustWriteDiagnosticInfoToString(DI: DiagnosticInfoRef, s: RustStringRef); pub fn LLVMRustGetDiagInfoKind(DI: DiagnosticInfoRef) -> DiagnosticKind; @@ -1687,15 +1686,15 @@ extern "C" { pub fn LLVMRustSetDataLayoutFromTargetMachine(M: &Module, TM: TargetMachineRef); pub fn LLVMRustBuildOperandBundleDef(Name: *const c_char, - Inputs: *const ValueRef, + Inputs: *const &Value, NumInputs: c_uint) -> OperandBundleDefRef; pub fn LLVMRustFreeOperandBundleDef(Bundle: OperandBundleDefRef); pub fn LLVMRustPositionBuilderAtStart(B: &Builder, BB: BasicBlockRef); - pub fn LLVMRustSetComdat(M: &Module, V: ValueRef, Name: *const c_char); - pub fn LLVMRustUnsetComdat(V: ValueRef); + pub fn LLVMRustSetComdat(M: &'a Module, V: &'a Value, Name: *const c_char); + pub fn LLVMRustUnsetComdat(V: &Value); pub fn LLVMRustSetModulePIELevel(M: &Module); pub fn LLVMRustModuleBufferCreate(M: &Module) -> *mut ModuleBuffer; pub fn LLVMRustModuleBufferPtr(p: *const ModuleBuffer) -> *const u8; diff --git a/src/librustc_codegen_llvm/llvm/mod.rs b/src/librustc_codegen_llvm/llvm/mod.rs index cf06e9532216a..b4b5ae42d02bd 100644 --- a/src/librustc_codegen_llvm/llvm/mod.rs +++ b/src/librustc_codegen_llvm/llvm/mod.rs @@ -42,7 +42,7 @@ impl LLVMRustResult { } } -pub fn AddFunctionAttrStringValue(llfn: ValueRef, +pub fn AddFunctionAttrStringValue(llfn: &'a Value, idx: AttributePlace, attr: &CStr, value: &CStr) { @@ -108,12 +108,12 @@ pub unsafe extern "C" fn LLVMRustStringWriteImpl(sr: RustStringRef, (*sr).borrow_mut().extend_from_slice(slice); } -pub fn SetInstructionCallConv(instr: ValueRef, cc: CallConv) { +pub fn SetInstructionCallConv(instr: &'a Value, cc: CallConv) { unsafe { LLVMSetInstructionCallConv(instr, cc as c_uint); } } -pub fn SetFunctionCallConv(fn_: ValueRef, cc: CallConv) { +pub fn SetFunctionCallConv(fn_: &'a Value, cc: CallConv) { unsafe { LLVMSetFunctionCallConv(fn_, cc as c_uint); } @@ -125,49 +125,49 @@ pub fn SetFunctionCallConv(fn_: ValueRef, cc: CallConv) { // 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: &Module, val: ValueRef) { +pub fn SetUniqueComdat(llmod: &Module, val: &'a Value) { unsafe { LLVMRustSetComdat(llmod, val, LLVMGetValueName(val)); } } -pub fn UnsetComdat(val: ValueRef) { +pub fn UnsetComdat(val: &'a Value) { unsafe { LLVMRustUnsetComdat(val); } } -pub fn SetUnnamedAddr(global: ValueRef, unnamed: bool) { +pub fn SetUnnamedAddr(global: &'a Value, unnamed: bool) { unsafe { LLVMSetUnnamedAddr(global, unnamed as Bool); } } -pub fn set_thread_local(global: ValueRef, is_thread_local: bool) { +pub fn set_thread_local(global: &'a Value, is_thread_local: bool) { unsafe { LLVMSetThreadLocal(global, is_thread_local as Bool); } } -pub fn set_thread_local_mode(global: ValueRef, mode: ThreadLocalMode) { +pub fn set_thread_local_mode(global: &'a Value, mode: ThreadLocalMode) { unsafe { LLVMSetThreadLocalMode(global, mode); } } impl Attribute { - pub fn apply_llfn(&self, idx: AttributePlace, llfn: ValueRef) { + pub fn apply_llfn(&self, idx: AttributePlace, llfn: &Value) { unsafe { LLVMRustAddFunctionAttribute(llfn, idx.as_uint(), *self) } } - pub fn apply_callsite(&self, idx: AttributePlace, callsite: ValueRef) { + pub fn apply_callsite(&self, idx: AttributePlace, callsite: &Value) { unsafe { LLVMRustAddCallSiteAttribute(callsite, idx.as_uint(), *self) } } - pub fn unapply_llfn(&self, idx: AttributePlace, llfn: ValueRef) { + pub fn unapply_llfn(&self, idx: AttributePlace, llfn: &Value) { unsafe { LLVMRustRemoveFunctionAttributes(llfn, idx.as_uint(), *self) } } - pub fn toggle_llfn(&self, idx: AttributePlace, llfn: ValueRef, set: bool) { + pub fn toggle_llfn(&self, idx: AttributePlace, llfn: &Value, set: bool) { if set { self.apply_llfn(idx, llfn); } else { @@ -226,7 +226,7 @@ pub fn mk_section_iter(llof: ObjectFileRef) -> SectionIter { } /// Safe wrapper around `LLVMGetParam`, because segfaults are no fun. -pub fn get_param(llfn: ValueRef, index: c_uint) -> ValueRef { +pub fn get_param(llfn: &'a Value, index: c_uint) -> &'a Value { unsafe { assert!(index < LLVMCountParams(llfn), "out of bounds argument access: {} out of {} arguments", index, LLVMCountParams(llfn)); @@ -265,7 +265,7 @@ pub struct OperandBundleDef { } impl OperandBundleDef { - pub fn new(name: &str, vals: &[ValueRef]) -> OperandBundleDef { + pub fn new(name: &str, vals: &[&'a Value]) -> OperandBundleDef { let name = CString::new(name).unwrap(); let def = unsafe { LLVMRustBuildOperandBundleDef(name.as_ptr(), vals.as_ptr(), vals.len() as c_uint) diff --git a/src/librustc_codegen_llvm/meth.rs b/src/librustc_codegen_llvm/meth.rs index c313c04d8047a..9c0dd0dc3d8b5 100644 --- a/src/librustc_codegen_llvm/meth.rs +++ b/src/librustc_codegen_llvm/meth.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use llvm::ValueRef; use abi::{FnType, FnTypeExt}; use callee; use common::*; @@ -17,6 +16,7 @@ use consts; use monomorphize; use type_::Type; use value::Value; + use rustc::ty::{self, Ty}; use rustc::ty::layout::HasDataLayout; use debuginfo; @@ -34,10 +34,10 @@ impl<'a, 'tcx> VirtualIndex { } pub fn get_fn(self, bx: &Builder<'a, 'll, 'tcx>, - llvtable: ValueRef, - fn_ty: &FnType<'tcx, Ty<'tcx>>) -> ValueRef { + llvtable: &'ll Value, + fn_ty: &FnType<'tcx, Ty<'tcx>>) -> &'ll Value { // Load the data pointer from the object. - debug!("get_fn({:?}, {:?})", Value(llvtable), self); + debug!("get_fn({:?}, {:?})", llvtable, self); let llvtable = bx.pointercast(llvtable, fn_ty.llvm_type(bx.cx).ptr_to().ptr_to()); let ptr_align = bx.tcx().data_layout.pointer_align; @@ -48,9 +48,9 @@ impl<'a, 'tcx> VirtualIndex { ptr } - pub fn get_usize(self, bx: &Builder<'a, 'll, 'tcx>, llvtable: ValueRef) -> ValueRef { + pub fn get_usize(self, bx: &Builder<'a, 'll, 'tcx>, llvtable: &'ll Value) -> &'ll Value { // Load the data pointer from the object. - debug!("get_int({:?}, {:?})", Value(llvtable), self); + debug!("get_int({:?}, {:?})", llvtable, self); let llvtable = bx.pointercast(llvtable, Type::isize(bx.cx).ptr_to()); let usize_align = bx.tcx().data_layout.pointer_align; @@ -69,11 +69,11 @@ impl<'a, 'tcx> VirtualIndex { /// The `trait_ref` encodes the erased self type. Hence if we are /// making an object `Foo` from a value of type `Foo`, then /// `trait_ref` would map `T:Trait`. -pub fn get_vtable<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, - ty: Ty<'tcx>, - trait_ref: Option>) - -> ValueRef -{ +pub fn get_vtable( + cx: &CodegenCx<'ll, 'tcx>, + ty: Ty<'tcx>, + trait_ref: Option>, +) -> &'ll Value { let tcx = cx.tcx; debug!("get_vtable(ty={:?}, trait_ref={:?})", ty, trait_ref); diff --git a/src/librustc_codegen_llvm/mir/analyze.rs b/src/librustc_codegen_llvm/mir/analyze.rs index 7bf548a6b12d5..2c2058035241f 100644 --- a/src/librustc_codegen_llvm/mir/analyze.rs +++ b/src/librustc_codegen_llvm/mir/analyze.rs @@ -34,7 +34,7 @@ pub fn non_ssa_locals(fx: &FunctionCx<'a, 'll, 'tcx>) -> BitVector { let layout = fx.cx.layout_of(ty); if layout.is_llvm_immediate() { // These sorts of types are immediates that we can store - // in an ValueRef without an alloca. + // in an Value without an alloca. } else if layout.is_llvm_scalar_pair() { // We allow pairs and uses of any of their 2 fields. } else { diff --git a/src/librustc_codegen_llvm/mir/block.rs b/src/librustc_codegen_llvm/mir/block.rs index 349978c18b7e6..587165dfe77f2 100644 --- a/src/librustc_codegen_llvm/mir/block.rs +++ b/src/librustc_codegen_llvm/mir/block.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use llvm::{self, ValueRef, BasicBlockRef}; +use llvm::{self, BasicBlockRef}; use rustc::middle::lang_items; use rustc::ty::{self, Ty, TypeFoldable}; use rustc::ty::layout::{self, LayoutOf}; @@ -24,6 +24,7 @@ use meth; use monomorphize; use type_of::LayoutLlvmExt; use type_::Type; +use value::Value; use syntax::symbol::Symbol; use syntax_pos::Pos; @@ -97,7 +98,7 @@ impl FunctionCx<'a, 'll, 'tcx> { } }; - let funclet_br = |this: &mut Self, bx: Builder, target: mir::BasicBlock| { + let funclet_br = |this: &mut Self, bx: Builder<'_, 'll, '_>, target: mir::BasicBlock| { let (lltarget, is_cleanupret) = lltarget(this, target); if is_cleanupret { // micro-optimization: generate a `ret` rather than a jump @@ -112,9 +113,9 @@ impl FunctionCx<'a, 'll, 'tcx> { this: &mut Self, bx: Builder<'a, 'll, 'tcx>, fn_ty: FnType<'tcx, Ty<'tcx>>, - fn_ptr: ValueRef, - llargs: &[ValueRef], - destination: Option<(ReturnDest<'tcx>, mir::BasicBlock)>, + fn_ptr: &'ll Value, + llargs: &[&'ll Value], + destination: Option<(ReturnDest<'ll, 'tcx>, mir::BasicBlock)>, cleanup: Option | { if let Some(cleanup) = cleanup { @@ -285,8 +286,14 @@ impl FunctionCx<'a, 'll, 'tcx> { } let place = self.codegen_place(&bx, location); - let mut args: &[_] = &[place.llval, place.llextra]; - args = &args[..1 + place.has_extra() as usize]; + let (args1, args2); + let mut args = if let Some(llextra) = place.llextra { + args2 = [place.llval, llextra]; + &args2[..] + } else { + args1 = [place.llval]; + &args1[..] + }; let (drop_fn, fn_ty) = match ty.sty { ty::TyDynamic(..) => { let fn_ty = drop_fn.ty(bx.cx.tcx); @@ -296,8 +303,9 @@ impl FunctionCx<'a, 'll, 'tcx> { &sig, ); let fn_ty = FnType::new_vtable(bx.cx, sig, &[]); + let vtable = args[1]; args = &args[..1]; - (meth::DESTRUCTOR.get_fn(&bx, place.llextra, &fn_ty), fn_ty) + (meth::DESTRUCTOR.get_fn(&bx, vtable, &fn_ty), fn_ty) } _ => { (callee::get_fn(bx.cx, drop_fn), @@ -628,8 +636,8 @@ impl FunctionCx<'a, 'll, 'tcx> { fn codegen_argument(&mut self, bx: &Builder<'a, 'll, 'tcx>, - op: OperandRef<'tcx>, - llargs: &mut Vec, + op: OperandRef<'ll, 'tcx>, + llargs: &mut Vec<&'ll Value>, arg: &ArgType<'tcx, Ty<'tcx>>) { // Fill padding with undef value, where applicable. if let Some(ty) = arg.pad { @@ -708,7 +716,7 @@ impl FunctionCx<'a, 'll, 'tcx> { fn codegen_arguments_untupled(&mut self, bx: &Builder<'a, 'll, 'tcx>, operand: &mir::Operand<'tcx>, - llargs: &mut Vec, + llargs: &mut Vec<&'ll Value>, args: &[ArgType<'tcx, Ty<'tcx>>]) { let tuple = self.codegen_operand(bx, operand); @@ -728,7 +736,7 @@ impl FunctionCx<'a, 'll, 'tcx> { } } - fn get_personality_slot(&mut self, bx: &Builder<'a, 'll, 'tcx>) -> PlaceRef<'tcx> { + fn get_personality_slot(&mut self, bx: &Builder<'a, 'll, 'tcx>) -> PlaceRef<'ll, 'tcx> { let cx = bx.cx; if let Some(slot) = self.personality_slot { slot @@ -803,8 +811,8 @@ impl FunctionCx<'a, 'll, 'tcx> { fn make_return_dest(&mut self, bx: &Builder<'a, 'll, 'tcx>, dest: &mir::Place<'tcx>, fn_ret: &ArgType<'tcx, Ty<'tcx>>, - llargs: &mut Vec, is_intrinsic: bool) - -> ReturnDest<'tcx> { + llargs: &mut Vec<&'ll Value>, is_intrinsic: bool) + -> ReturnDest<'ll, 'tcx> { // If the return is ignored, we can just return a do-nothing ReturnDest if fn_ret.is_ignore() { return ReturnDest::Nothing; @@ -886,7 +894,7 @@ impl FunctionCx<'a, 'll, 'tcx> { fn codegen_transmute_into(&mut self, bx: &Builder<'a, 'll, 'tcx>, src: &mir::Operand<'tcx>, - dst: PlaceRef<'tcx>) { + dst: PlaceRef<'ll, 'tcx>) { let src = self.codegen_operand(bx, src); let llty = src.layout.llvm_type(bx.cx); let cast_ptr = bx.pointercast(dst.llval, llty.ptr_to()); @@ -898,9 +906,9 @@ impl FunctionCx<'a, 'll, 'tcx> { // Stores the return value of a function call into it's final location. fn store_return(&mut self, bx: &Builder<'a, 'll, 'tcx>, - dest: ReturnDest<'tcx>, + dest: ReturnDest<'ll, 'tcx>, ret_ty: &ArgType<'tcx, Ty<'tcx>>, - llval: ValueRef) { + llval: &'ll Value) { use self::ReturnDest::*; match dest { @@ -929,13 +937,13 @@ impl FunctionCx<'a, 'll, 'tcx> { } } -enum ReturnDest<'tcx> { +enum ReturnDest<'ll, 'tcx> { // Do nothing, the return value is indirect or ignored Nothing, // Store the return value to the pointer - Store(PlaceRef<'tcx>), + Store(PlaceRef<'ll, 'tcx>), // Stores an indirect return value to an operand local place - IndirectOperand(PlaceRef<'tcx>, mir::Local), + IndirectOperand(PlaceRef<'ll, 'tcx>, mir::Local), // Stores a direct return value to an operand local place DirectOperand(mir::Local) } diff --git a/src/librustc_codegen_llvm/mir/constant.rs b/src/librustc_codegen_llvm/mir/constant.rs index 3fc86af3e6d40..341ed9df64b59 100644 --- a/src/librustc_codegen_llvm/mir/constant.rs +++ b/src/librustc_codegen_llvm/mir/constant.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use llvm::{self, ValueRef}; +use llvm; use rustc::mir::interpret::ConstEvalErr; use rustc_mir::interpret::{read_target_uint, const_val_field}; use rustc::hir::def_id::DefId; @@ -26,14 +26,17 @@ use type_of::LayoutLlvmExt; use type_::Type; use syntax::ast::Mutability; use syntax::codemap::Span; +use value::Value; use super::super::callee; use super::FunctionCx; -pub fn scalar_to_llvm(cx: &CodegenCx, - cv: Scalar, - layout: &layout::Scalar, - llty: &Type) -> ValueRef { +pub fn scalar_to_llvm( + cx: &CodegenCx<'ll, '_>, + cv: Scalar, + layout: &layout::Scalar, + llty: &'ll Type, +) -> &'ll Value { let bitsize = if layout.is_bool() { 1 } else { layout.value.size(cx).bits() }; match cv { Scalar::Bits { defined, .. } if (defined as u64) < bitsize || defined == 0 => { @@ -81,7 +84,7 @@ pub fn scalar_to_llvm(cx: &CodegenCx, } } -pub fn const_alloc_to_llvm(cx: &CodegenCx, alloc: &Allocation) -> ValueRef { +pub fn const_alloc_to_llvm(cx: &CodegenCx<'ll, '_>, alloc: &Allocation) -> &'ll Value { let mut llvals = Vec::with_capacity(alloc.relocations.len() + 1); let layout = cx.data_layout(); let pointer_size = layout.pointer_size.bytes() as usize; @@ -116,10 +119,10 @@ pub fn const_alloc_to_llvm(cx: &CodegenCx, alloc: &Allocation) -> ValueRef { C_struct(cx, &llvals, true) } -pub fn codegen_static_initializer<'a, 'tcx>( - cx: &CodegenCx<'a, 'tcx>, +pub fn codegen_static_initializer( + cx: &CodegenCx<'ll, 'tcx>, def_id: DefId, -) -> Result<(ValueRef, &'tcx Allocation), Lrc>> { +) -> Result<(&'ll Value, &'tcx Allocation), Lrc>> { let instance = ty::Instance::mono(cx.tcx, def_id); let cid = GlobalId { instance, @@ -172,7 +175,7 @@ impl FunctionCx<'a, 'll, 'tcx> { span: Span, ty: Ty<'tcx>, constant: Result<&'tcx ty::Const<'tcx>, Lrc>>, - ) -> (ValueRef, Ty<'tcx>) { + ) -> (&'ll Value, Ty<'tcx>) { constant .and_then(|c| { let field_ty = c.ty.builtin_index().unwrap(); @@ -180,7 +183,7 @@ impl FunctionCx<'a, 'll, 'tcx> { ty::TyArray(_, n) => n.unwrap_usize(bx.tcx()), ref other => bug!("invalid simd shuffle type: {}", other), }; - let values: Result, Lrc<_>> = (0..fields).map(|field| { + let values: Result, Lrc<_>> = (0..fields).map(|field| { let field = const_val_field( bx.tcx(), ty::ParamEnv::reveal_all(), diff --git a/src/librustc_codegen_llvm/mir/mod.rs b/src/librustc_codegen_llvm/mir/mod.rs index 62369ea5792bf..be9cd005013f7 100644 --- a/src/librustc_codegen_llvm/mir/mod.rs +++ b/src/librustc_codegen_llvm/mir/mod.rs @@ -10,7 +10,7 @@ use common::{C_i32, C_null}; use libc::c_uint; -use llvm::{self, ValueRef, BasicBlockRef}; +use llvm::{self, BasicBlockRef}; use llvm::debuginfo::DIScope; use rustc::ty::{self, Ty, TypeFoldable, UpvarSubsts}; use rustc::ty::layout::{LayoutOf, TyLayout}; @@ -24,6 +24,7 @@ use debuginfo::{self, declare_local, VariableAccess, VariableKind, FunctionDebug use monomorphize::Instance; use abi::{ArgTypeExt, FnType, FnTypeExt, PassMode}; use type_::Type; +use value::Value; use syntax_pos::{DUMMY_SP, NO_EXPANSION, BytePos, Span}; use syntax::symbol::keywords; @@ -49,7 +50,7 @@ pub struct FunctionCx<'a, 'll: 'a, 'tcx: 'll> { debug_context: FunctionDebugContext<'ll>, - llfn: ValueRef, + llfn: &'ll Value, cx: &'a CodegenCx<'ll, 'tcx>, @@ -62,7 +63,7 @@ pub struct FunctionCx<'a, 'll: 'a, 'tcx: 'll> { /// don't really care about it very much. Anyway, this value /// contains an alloca into which the personality is stored and /// then later loaded when generating the DIVERGE_BLOCK. - personality_slot: Option>, + personality_slot: Option>, /// A `Block` for each MIR `BasicBlock` blocks: IndexVec, @@ -72,7 +73,7 @@ pub struct FunctionCx<'a, 'll: 'a, 'tcx: 'll> { /// When targeting MSVC, this stores the cleanup info for each funclet /// BB. This is initialized as we compute the funclets' head block in RPO. - funclets: &'a IndexVec>, + funclets: &'a IndexVec>>, /// This stores the landing-pad block for a given BB, computed lazily on GNU /// and eagerly on MSVC. @@ -96,7 +97,7 @@ pub struct FunctionCx<'a, 'll: 'a, 'tcx: 'll> { /// /// Avoiding allocs can also be important for certain intrinsics, /// notably `expect`. - locals: IndexVec>, + locals: IndexVec>, /// Debug information for MIR scopes. scopes: IndexVec>, @@ -177,13 +178,13 @@ impl FunctionCx<'a, 'll, 'tcx> { } } -enum LocalRef<'tcx> { - Place(PlaceRef<'tcx>), - Operand(Option>), +enum LocalRef<'ll, 'tcx> { + Place(PlaceRef<'ll, 'tcx>), + Operand(Option>), } -impl<'a, 'tcx> LocalRef<'tcx> { - fn new_operand(cx: &CodegenCx<'a, 'tcx>, layout: TyLayout<'tcx>) -> LocalRef<'tcx> { +impl LocalRef<'ll, 'tcx> { + fn new_operand(cx: &CodegenCx<'ll, 'tcx>, layout: TyLayout<'tcx>) -> LocalRef<'ll, 'tcx> { if layout.is_zst() { // Zero-size temporaries aren't always initialized, which // doesn't matter because they don't contain data, but @@ -199,7 +200,7 @@ impl<'a, 'tcx> LocalRef<'tcx> { pub fn codegen_mir( cx: &'a CodegenCx<'ll, 'tcx>, - llfn: ValueRef, + llfn: &'ll Value, mir: &'a Mir<'tcx>, instance: Instance<'tcx>, sig: ty::FnSig<'tcx>, @@ -349,7 +350,7 @@ fn create_funclets( cleanup_kinds: &IndexVec, block_bxs: &IndexVec) -> (IndexVec>, - IndexVec>) + IndexVec>>) { block_bxs.iter_enumerated().zip(cleanup_kinds).map(|((bb, &llbb), cleanup_kind)| { match *cleanup_kind { @@ -409,7 +410,7 @@ fn create_funclets( }).unzip() } -/// Produce, for each argument, a `ValueRef` pointing at the +/// Produce, for each argument, a `Value` pointing at the /// argument's value. As arguments are places, these are always /// indirect. fn arg_local_refs( @@ -417,7 +418,7 @@ fn arg_local_refs( fx: &FunctionCx<'a, 'll, 'tcx>, scopes: &IndexVec>, memory_locals: &BitVector, -) -> Vec> { +) -> Vec> { let mir = fx.mir; let tcx = bx.tcx(); let mut idx = 0; diff --git a/src/librustc_codegen_llvm/mir/operand.rs b/src/librustc_codegen_llvm/mir/operand.rs index 790dbae447bd4..f8b18f2f8b8aa 100644 --- a/src/librustc_codegen_llvm/mir/operand.rs +++ b/src/librustc_codegen_llvm/mir/operand.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use llvm::ValueRef; use rustc::mir::interpret::ConstEvalErr; use rustc::mir; use rustc::mir::interpret::ConstValue; @@ -32,31 +31,15 @@ use super::place::PlaceRef; /// The representation of a Rust value. The enum variant is in fact /// uniquely determined by the value's type, but is kept as a /// safety check. -#[derive(Copy, Clone)] -pub enum OperandValue { +#[derive(Copy, Clone, Debug)] +pub enum OperandValue<'ll> { /// A reference to the actual operand. The data is guaranteed /// to be valid for the operand's lifetime. - Ref(ValueRef, Align), + Ref(&'ll Value, Align), /// A single LLVM value. - Immediate(ValueRef), + Immediate(&'ll Value), /// A pair of immediate LLVM values. Used by fat pointers too. - Pair(ValueRef, ValueRef) -} - -impl fmt::Debug for OperandValue { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - OperandValue::Ref(r, align) => { - write!(f, "Ref({:?}, {:?})", Value(r), align) - } - OperandValue::Immediate(i) => { - write!(f, "Immediate({:?})", Value(i)) - } - OperandValue::Pair(a, b) => { - write!(f, "Pair({:?}, {:?})", Value(a), Value(b)) - } - } - } + Pair(&'ll Value, &'ll Value) } /// An `OperandRef` is an "SSA" reference to a Rust value, along with @@ -68,23 +51,23 @@ impl fmt::Debug for OperandValue { /// directly is sure to cause problems -- use `OperandRef::store` /// instead. #[derive(Copy, Clone)] -pub struct OperandRef<'tcx> { +pub struct OperandRef<'ll, 'tcx> { // The value. - pub val: OperandValue, + pub val: OperandValue<'ll>, // The layout of value, based on its Rust type. pub layout: TyLayout<'tcx>, } -impl<'tcx> fmt::Debug for OperandRef<'tcx> { +impl fmt::Debug for OperandRef<'ll, 'tcx> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "OperandRef({:?} @ {:?})", self.val, self.layout) } } -impl<'a, 'tcx> OperandRef<'tcx> { - pub fn new_zst(cx: &CodegenCx<'a, 'tcx>, - layout: TyLayout<'tcx>) -> OperandRef<'tcx> { +impl OperandRef<'ll, 'tcx> { + pub fn new_zst(cx: &CodegenCx<'ll, 'tcx>, + layout: TyLayout<'tcx>) -> OperandRef<'ll, 'tcx> { assert!(layout.is_zst()); OperandRef { val: OperandValue::Immediate(C_undef(layout.immediate_llvm_type(cx))), @@ -94,7 +77,7 @@ impl<'a, 'tcx> OperandRef<'tcx> { pub fn from_const(bx: &Builder<'a, 'll, 'tcx>, val: &'tcx ty::Const<'tcx>) - -> Result, Lrc>> { + -> Result, Lrc>> { let layout = bx.cx.layout_of(val.ty); if layout.is_zst() { @@ -148,19 +131,19 @@ impl<'a, 'tcx> OperandRef<'tcx> { /// Asserts that this operand refers to a scalar and returns /// a reference to its value. - pub fn immediate(self) -> ValueRef { + pub fn immediate(self) -> &'ll Value { match self.val { OperandValue::Immediate(s) => s, _ => bug!("not immediate: {:?}", self) } } - pub fn deref(self, cx: &CodegenCx<'a, 'tcx>) -> PlaceRef<'tcx> { + pub fn deref(self, cx: &CodegenCx<'ll, 'tcx>) -> PlaceRef<'ll, 'tcx> { let projected_ty = self.layout.ty.builtin_deref(true) .unwrap_or_else(|| bug!("deref of non-pointer {:?}", self)).ty; let (llptr, llextra) = match self.val { - OperandValue::Immediate(llptr) => (llptr, 0 as *mut _), - OperandValue::Pair(llptr, llextra) => (llptr, llextra), + OperandValue::Immediate(llptr) => (llptr, None), + OperandValue::Pair(llptr, llextra) => (llptr, Some(llextra)), OperandValue::Ref(..) => bug!("Deref of by-Ref operand {:?}", self) }; let layout = cx.layout_of(projected_ty); @@ -174,7 +157,7 @@ impl<'a, 'tcx> OperandRef<'tcx> { /// If this operand is a `Pair`, we return an aggregate with the two values. /// For other cases, see `immediate`. - pub fn immediate_or_packed_pair(self, bx: &Builder<'a, 'll, 'tcx>) -> ValueRef { + pub fn immediate_or_packed_pair(self, bx: &Builder<'a, 'll, 'tcx>) -> &'ll Value { if let OperandValue::Pair(a, b) = self.val { let llty = self.layout.llvm_type(bx.cx); debug!("Operand::immediate_or_packed_pair: packing {:?} into {:?}", @@ -191,9 +174,9 @@ impl<'a, 'tcx> OperandRef<'tcx> { /// If the type is a pair, we return a `Pair`, otherwise, an `Immediate`. pub fn from_immediate_or_packed_pair(bx: &Builder<'a, 'll, 'tcx>, - llval: ValueRef, + llval: &'ll Value, layout: TyLayout<'tcx>) - -> OperandRef<'tcx> { + -> OperandRef<'ll, 'tcx> { let val = if let layout::Abi::ScalarPair(ref a, ref b) = layout.abi { debug!("Operand::from_immediate_or_packed_pair: unpacking {:?} @ {:?}", llval, layout); @@ -208,7 +191,7 @@ impl<'a, 'tcx> OperandRef<'tcx> { OperandRef { val, layout } } - pub fn extract_field(&self, bx: &Builder<'a, 'll, 'tcx>, i: usize) -> OperandRef<'tcx> { + pub fn extract_field(&self, bx: &Builder<'a, 'll, 'tcx>, i: usize) -> OperandRef<'ll, 'tcx> { let field = self.layout.field(bx.cx, i); let offset = self.layout.fields.offset(i); @@ -266,24 +249,24 @@ impl<'a, 'tcx> OperandRef<'tcx> { } } -impl<'a, 'tcx> OperandValue { - pub fn store(self, bx: &Builder<'a, 'll, 'tcx>, dest: PlaceRef<'tcx>) { +impl OperandValue<'ll> { + pub fn store(self, bx: &Builder<'a, 'll, 'tcx>, dest: PlaceRef<'ll, 'tcx>) { self.store_with_flags(bx, dest, MemFlags::empty()); } - pub fn volatile_store(self, bx: &Builder<'a, 'll, 'tcx>, dest: PlaceRef<'tcx>) { + pub fn volatile_store(self, bx: &Builder<'a, 'll, 'tcx>, dest: PlaceRef<'ll, 'tcx>) { self.store_with_flags(bx, dest, MemFlags::VOLATILE); } - pub fn unaligned_volatile_store(self, bx: &Builder<'a, 'll, 'tcx>, dest: PlaceRef<'tcx>) { + pub fn unaligned_volatile_store(self, bx: &Builder<'a, 'll, 'tcx>, dest: PlaceRef<'ll, 'tcx>) { self.store_with_flags(bx, dest, MemFlags::VOLATILE | MemFlags::UNALIGNED); } - pub fn nontemporal_store(self, bx: &Builder<'a, 'll, 'tcx>, dest: PlaceRef<'tcx>) { + pub fn nontemporal_store(self, bx: &Builder<'a, 'll, 'tcx>, dest: PlaceRef<'ll, 'tcx>) { self.store_with_flags(bx, dest, MemFlags::NONTEMPORAL); } - fn store_with_flags(self, bx: &Builder<'a, 'll, 'tcx>, dest: PlaceRef<'tcx>, flags: MemFlags) { + fn store_with_flags(self, bx: &Builder<'a, 'll, 'tcx>, dest: PlaceRef<'ll, 'tcx>, flags: MemFlags) { debug!("OperandRef::store: operand={:?}, dest={:?}", self, dest); // Avoid generating stores of zero-sized values, because the only way to have a zero-sized // value is through `undef`, and store itself is useless. @@ -314,7 +297,7 @@ impl FunctionCx<'a, 'll, 'tcx> { fn maybe_codegen_consume_direct(&mut self, bx: &Builder<'a, 'll, 'tcx>, place: &mir::Place<'tcx>) - -> Option> + -> Option> { debug!("maybe_codegen_consume_direct(place={:?})", place); @@ -362,7 +345,7 @@ impl FunctionCx<'a, 'll, 'tcx> { pub fn codegen_consume(&mut self, bx: &Builder<'a, 'll, 'tcx>, place: &mir::Place<'tcx>) - -> OperandRef<'tcx> + -> OperandRef<'ll, 'tcx> { debug!("codegen_consume(place={:?})", place); @@ -386,7 +369,7 @@ impl FunctionCx<'a, 'll, 'tcx> { pub fn codegen_operand(&mut self, bx: &Builder<'a, 'll, 'tcx>, operand: &mir::Operand<'tcx>) - -> OperandRef<'tcx> + -> OperandRef<'ll, 'tcx> { debug!("codegen_operand(operand={:?})", operand); diff --git a/src/librustc_codegen_llvm/mir/place.rs b/src/librustc_codegen_llvm/mir/place.rs index 9cb513e21586a..abc3dbdab2f5b 100644 --- a/src/librustc_codegen_llvm/mir/place.rs +++ b/src/librustc_codegen_llvm/mir/place.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use llvm::{self, ValueRef, LLVMConstInBoundsGEP}; +use llvm::{self, LLVMConstInBoundsGEP}; use rustc::ty::{self, Ty}; use rustc::ty::layout::{self, Align, TyLayout, LayoutOf, Size}; use rustc::mir; @@ -28,12 +28,12 @@ use super::{FunctionCx, LocalRef}; use super::operand::{OperandRef, OperandValue}; #[derive(Copy, Clone, Debug)] -pub struct PlaceRef<'tcx> { +pub struct PlaceRef<'ll, 'tcx> { /// Pointer to the contents of the place - pub llval: ValueRef, + pub llval: &'ll Value, /// This place's extra data if it is unsized, or null - pub llextra: ValueRef, + pub llextra: Option<&'ll Value>, /// Monomorphized type of this place, including variant information pub layout: TyLayout<'tcx>, @@ -42,14 +42,15 @@ pub struct PlaceRef<'tcx> { pub align: Align, } -impl<'a, 'tcx> PlaceRef<'tcx> { - pub fn new_sized(llval: ValueRef, - layout: TyLayout<'tcx>, - align: Align) - -> PlaceRef<'tcx> { +impl PlaceRef<'ll, 'tcx> { + pub fn new_sized( + llval: &'ll Value, + layout: TyLayout<'tcx>, + align: Align, + ) -> PlaceRef<'ll, 'tcx> { PlaceRef { llval, - llextra: 0 as *mut _, + llextra: None, layout, align } @@ -60,7 +61,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> { layout: TyLayout<'tcx>, alloc: &mir::interpret::Allocation, offset: Size, - ) -> PlaceRef<'tcx> { + ) -> PlaceRef<'ll, 'tcx> { let init = const_alloc_to_llvm(bx.cx, alloc); let base_addr = consts::addr_of(bx.cx, init, layout.align, "byte_str"); @@ -74,18 +75,17 @@ impl<'a, 'tcx> PlaceRef<'tcx> { } pub fn alloca(bx: &Builder<'a, 'll, 'tcx>, layout: TyLayout<'tcx>, name: &str) - -> PlaceRef<'tcx> { + -> PlaceRef<'ll, 'tcx> { debug!("alloca({:?}: {:?})", name, layout); let tmp = bx.alloca(layout.llvm_type(bx.cx), name, layout.align); Self::new_sized(tmp, layout, layout.align) } - pub fn len(&self, cx: &CodegenCx<'a, 'tcx>) -> ValueRef { + pub fn len(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Value { if let layout::FieldPlacement::Array { count, .. } = self.layout.fields { if self.layout.is_unsized() { - assert!(self.has_extra()); assert_eq!(count, 0); - self.llextra + self.llextra.unwrap() } else { C_usize(cx, count) } @@ -94,14 +94,10 @@ impl<'a, 'tcx> PlaceRef<'tcx> { } } - pub fn has_extra(&self) -> bool { - !self.llextra.is_null() - } - - pub fn load(&self, bx: &Builder<'a, 'll, 'tcx>) -> OperandRef<'tcx> { + pub fn load(&self, bx: &Builder<'a, 'll, 'tcx>) -> OperandRef<'ll, 'tcx> { debug!("PlaceRef::load: {:?}", self); - assert!(!self.has_extra()); + assert_eq!(self.llextra, None); if self.layout.is_zst() { return OperandRef::new_zst(bx.cx, self.layout); @@ -124,23 +120,21 @@ impl<'a, 'tcx> PlaceRef<'tcx> { }; let val = if self.layout.is_llvm_immediate() { - let mut const_llval = 0 as *mut _; + let mut const_llval = None; unsafe { - let global = llvm::LLVMIsAGlobalVariable(self.llval); - if !global.is_null() && llvm::LLVMIsGlobalConstant(global) == llvm::True { - const_llval = llvm::LLVMGetInitializer(global); + if let Some(global) = llvm::LLVMIsAGlobalVariable(self.llval) { + if llvm::LLVMIsGlobalConstant(global) == llvm::True { + const_llval = llvm::LLVMGetInitializer(global); + } } } - - let llval = if !const_llval.is_null() { - const_llval - } else { + let llval = const_llval.unwrap_or_else(|| { let load = bx.load(self.llval, self.align); if let layout::Abi::Scalar(ref scalar) = self.layout.abi { scalar_load_metadata(load, scalar); } load - }; + }); OperandValue::Immediate(base::to_immediate(bx, llval, self.layout)) } else if let layout::Abi::ScalarPair(ref a, ref b) = self.layout.abi { let load = |i, scalar: &layout::Scalar| { @@ -162,7 +156,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> { } /// Access a field, at a point when the value's case is known. - pub fn project_field(self, bx: &Builder<'a, 'll, 'tcx>, ix: usize) -> PlaceRef<'tcx> { + pub fn project_field(self, bx: &Builder<'a, 'll, 'tcx>, ix: usize) -> PlaceRef<'ll, 'tcx> { let cx = bx.cx; let field = self.layout.field(cx, ix); let offset = self.layout.fields.offset(ix); @@ -185,7 +179,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> { llextra: if cx.type_has_metadata(field.ty) { self.llextra } else { - 0 as *mut _ + None }, layout: field, align, @@ -197,9 +191,9 @@ impl<'a, 'tcx> PlaceRef<'tcx> { // * known alignment - sized types, [T], str or a foreign type // * packed struct - there is no alignment padding match field.ty.sty { - _ if !self.has_extra() => { + _ if self.llextra.is_none() => { debug!("Unsized field `{}`, of `{:?}` has no metadata for adjustment", - ix, Value(self.llval)); + ix, self.llval); return simple(); } _ if !field.is_unsized() => return simple(), @@ -247,7 +241,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> { let offset = bx.and(bx.add(unaligned_offset, align_sub_1), bx.neg(unsized_align)); - debug!("struct_field_ptr: DST field offset: {:?}", Value(offset)); + debug!("struct_field_ptr: DST field offset: {:?}", offset); // Cast and adjust pointer let byte_ptr = bx.pointercast(self.llval, Type::i8p(cx)); @@ -266,7 +260,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> { } /// Obtain the actual discriminant of a value. - pub fn codegen_get_discr(self, bx: &Builder<'a, 'll, 'tcx>, cast_to: Ty<'tcx>) -> ValueRef { + pub fn codegen_get_discr(self, bx: &Builder<'a, 'll, 'tcx>, cast_to: Ty<'tcx>) -> &'ll Value { let cast_to = bx.cx.layout_of(cast_to).immediate_llvm_type(bx.cx); if self.layout.abi == layout::Abi::Uninhabited { return C_undef(cast_to); @@ -384,18 +378,18 @@ impl<'a, 'tcx> PlaceRef<'tcx> { } } - pub fn project_index(&self, bx: &Builder<'a, 'll, 'tcx>, llindex: ValueRef) - -> PlaceRef<'tcx> { + pub fn project_index(&self, bx: &Builder<'a, 'll, 'tcx>, llindex: &'ll Value) + -> PlaceRef<'ll, 'tcx> { PlaceRef { llval: bx.inbounds_gep(self.llval, &[C_usize(bx.cx, 0), llindex]), - llextra: 0 as *mut _, + llextra: None, layout: self.layout.field(bx.cx, 0), align: self.align } } pub fn project_downcast(&self, bx: &Builder<'a, 'll, 'tcx>, variant_index: usize) - -> PlaceRef<'tcx> { + -> PlaceRef<'ll, 'tcx> { let mut downcast = *self; downcast.layout = self.layout.for_variant(bx.cx, variant_index); @@ -419,7 +413,7 @@ impl FunctionCx<'a, 'll, 'tcx> { pub fn codegen_place(&mut self, bx: &Builder<'a, 'll, 'tcx>, place: &mir::Place<'tcx>) - -> PlaceRef<'tcx> { + -> PlaceRef<'ll, 'tcx> { debug!("codegen_place(place={:?})", place); let cx = bx.cx; @@ -511,9 +505,8 @@ impl FunctionCx<'a, 'll, 'tcx> { subslice.layout = bx.cx.layout_of(self.monomorphize(&projected_ty)); if subslice.layout.is_unsized() { - assert!(cg_base.has_extra()); - subslice.llextra = bx.sub(cg_base.llextra, - C_usize(bx.cx, (from as u64) + (to as u64))); + subslice.llextra = Some(bx.sub(cg_base.llextra.unwrap(), + C_usize(bx.cx, (from as u64) + (to as u64)))); } // Cast the place pointer type to the new diff --git a/src/librustc_codegen_llvm/mir/rvalue.rs b/src/librustc_codegen_llvm/mir/rvalue.rs index ca61f94e42817..02b5c27840eab 100644 --- a/src/librustc_codegen_llvm/mir/rvalue.rs +++ b/src/librustc_codegen_llvm/mir/rvalue.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use llvm::{self, ValueRef}; +use llvm; use rustc::ty::{self, Ty}; use rustc::ty::cast::{CastTy, IntTy}; use rustc::ty::layout::{self, LayoutOf}; @@ -35,12 +35,12 @@ use super::place::PlaceRef; impl FunctionCx<'a, 'll, 'tcx> { pub fn codegen_rvalue(&mut self, bx: Builder<'a, 'll, 'tcx>, - dest: PlaceRef<'tcx>, + dest: PlaceRef<'ll, 'tcx>, rvalue: &mir::Rvalue<'tcx>) -> Builder<'a, 'll, 'tcx> { debug!("codegen_rvalue(dest.llval={:?}, rvalue={:?})", - Value(dest.llval), rvalue); + dest.llval, rvalue); match *rvalue { mir::Rvalue::Use(ref operand) => { @@ -178,7 +178,7 @@ impl FunctionCx<'a, 'll, 'tcx> { pub fn codegen_rvalue_operand(&mut self, bx: Builder<'a, 'll, 'tcx>, rvalue: &mir::Rvalue<'tcx>) - -> (Builder<'a, 'll, 'tcx>, OperandRef<'tcx>) + -> (Builder<'a, 'll, 'tcx>, OperandRef<'ll, 'tcx>) { assert!(self.rvalue_creates_operand(rvalue), "cannot codegen {:?} to operand", rvalue); @@ -371,7 +371,7 @@ impl FunctionCx<'a, 'll, 'tcx> { let val = if !bx.cx.type_has_metadata(ty) { OperandValue::Immediate(cg_place.llval) } else { - OperandValue::Pair(cg_place.llval, cg_place.llextra) + OperandValue::Pair(cg_place.llval, cg_place.llextra.unwrap()) }; (bx, OperandRef { val, @@ -511,10 +511,11 @@ impl FunctionCx<'a, 'll, 'tcx> { } } - fn evaluate_array_len(&mut self, - bx: &Builder<'a, 'll, 'tcx>, - place: &mir::Place<'tcx>) -> ValueRef - { + fn evaluate_array_len( + &mut self, + bx: &Builder<'a, 'll, 'tcx>, + place: &mir::Place<'tcx>, + ) -> &'ll Value { // ZST are passed as operands and require special handling // because codegen_place() panics if Local is operand. if let mir::Place::Local(index) = *place { @@ -530,12 +531,14 @@ impl FunctionCx<'a, 'll, 'tcx> { return cg_value.len(bx.cx); } - pub fn codegen_scalar_binop(&mut self, - bx: &Builder<'a, 'll, 'tcx>, - op: mir::BinOp, - lhs: ValueRef, - rhs: ValueRef, - input_ty: Ty<'tcx>) -> ValueRef { + pub fn codegen_scalar_binop( + &mut self, + bx: &Builder<'a, 'll, 'tcx>, + op: mir::BinOp, + lhs: &'ll Value, + rhs: &'ll Value, + input_ty: Ty<'tcx>, + ) -> &'ll Value { let is_float = input_ty.is_fp(); let is_signed = input_ty.is_signed(); let is_nil = input_ty.is_nil(); @@ -596,15 +599,16 @@ impl FunctionCx<'a, 'll, 'tcx> { } } - pub fn codegen_fat_ptr_binop(&mut self, - bx: &Builder<'a, 'll, 'tcx>, - op: mir::BinOp, - lhs_addr: ValueRef, - lhs_extra: ValueRef, - rhs_addr: ValueRef, - rhs_extra: ValueRef, - _input_ty: Ty<'tcx>) - -> ValueRef { + pub fn codegen_fat_ptr_binop( + &mut self, + bx: &Builder<'a, 'll, 'tcx>, + op: mir::BinOp, + lhs_addr: &'ll Value, + lhs_extra: &'ll Value, + rhs_addr: &'ll Value, + rhs_extra: &'ll Value, + _input_ty: Ty<'tcx>, + ) -> &'ll Value { match op { mir::BinOp::Eq => { bx.and( @@ -646,9 +650,9 @@ impl FunctionCx<'a, 'll, 'tcx> { pub fn codegen_scalar_checked_binop(&mut self, bx: &Builder<'a, 'll, 'tcx>, op: mir::BinOp, - lhs: ValueRef, - rhs: ValueRef, - input_ty: Ty<'tcx>) -> OperandValue { + lhs: &'ll Value, + rhs: &'ll Value, + input_ty: Ty<'tcx>) -> OperandValue<'ll> { // This case can currently arise only from functions marked // with #[rustc_inherit_overflow_checks] and inlined from // another crate (mostly core::num generic/#[inline] fns), @@ -721,7 +725,7 @@ enum OverflowOp { Add, Sub, Mul } -fn get_overflow_intrinsic(oop: OverflowOp, bx: &Builder, ty: Ty) -> ValueRef { +fn get_overflow_intrinsic(oop: OverflowOp, bx: &Builder<'_, 'll, '_>, ty: Ty) -> &'ll Value { use syntax::ast::IntTy::*; use syntax::ast::UintTy::*; use rustc::ty::{TyInt, TyUint}; @@ -798,9 +802,9 @@ fn get_overflow_intrinsic(oop: OverflowOp, bx: &Builder, ty: Ty) -> ValueRef { fn cast_int_to_float(bx: &Builder<'_, 'll, '_>, signed: bool, - x: ValueRef, + x: &'ll Value, int_ty: &'ll Type, - float_ty: &'ll Type) -> ValueRef { + float_ty: &'ll Type) -> &'ll Value { // Most integer types, even i128, fit into [-f32::MAX, f32::MAX] after rounding. // It's only u128 -> f32 that can cause overflows (i.e., should yield infinity). // LLVM's uitofp produces undef in those cases, so we manually check for that case. @@ -828,9 +832,9 @@ fn cast_int_to_float(bx: &Builder<'_, 'll, '_>, fn cast_float_to_int(bx: &Builder<'_, 'll, '_>, signed: bool, - x: ValueRef, + x: &'ll Value, float_ty: &'ll Type, - int_ty: &'ll Type) -> ValueRef { + int_ty: &'ll Type) -> &'ll Value { let fptosui_result = if signed { bx.fptosi(x, int_ty) } else { diff --git a/src/librustc_codegen_llvm/value.rs b/src/librustc_codegen_llvm/value.rs index 287ad87caacf9..3328948c2951e 100644 --- a/src/librustc_codegen_llvm/value.rs +++ b/src/librustc_codegen_llvm/value.rs @@ -8,17 +8,32 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +pub use llvm::Value; + use llvm; use std::fmt; +use std::hash::{Hash, Hasher}; + +impl PartialEq for Value { + fn eq(&self, other: &Self) -> bool { + self as *const _ == other as *const _ + } +} + +impl Eq for Value {} + +impl Hash for Value { + fn hash(&self, hasher: &mut H) { + (self as *const Self).hash(hasher); + } +} -#[derive(Copy, Clone, PartialEq)] -pub struct Value(pub llvm::ValueRef); impl fmt::Debug for Value { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.write_str(&llvm::build_string(|s| unsafe { - llvm::LLVMRustWriteValueToString(self.0, s); + llvm::LLVMRustWriteValueToString(self, s); }).expect("nun-UTF8 value description from LLVM")) } } From 3eb50358e488e81c2b6d41c4237d605792923eb2 Mon Sep 17 00:00:00 2001 From: Irina Popa Date: Tue, 10 Jul 2018 14:34:34 +0300 Subject: [PATCH 12/36] rustc_codegen_llvm: use safe references for BasicBlock. --- src/librustc_codegen_llvm/builder.rs | 38 ++++++++++---------- src/librustc_codegen_llvm/llvm/ffi.rs | 49 +++++++++++++------------- src/librustc_codegen_llvm/mir/block.rs | 8 ++--- src/librustc_codegen_llvm/mir/mod.rs | 14 ++++---- 4 files changed, 54 insertions(+), 55 deletions(-) diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index 19ae990fa65ff..dbc16cbbf0ded 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -12,7 +12,7 @@ use llvm::{AtomicRmwBinOp, AtomicOrdering, SynchronizationScope, AsmDialect}; use llvm::{Opcode, IntPredicate, RealPredicate, False, OperandBundleDef}; -use llvm::{self, BasicBlockRef}; +use llvm::{self, BasicBlock}; use common::*; use type_::Type; use value::Value; @@ -102,7 +102,7 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn llbb(&self) -> BasicBlockRef { + pub fn llbb(&self) -> &'ll BasicBlock { unsafe { llvm::LLVMGetInsertBlock(self.llbuilder) } @@ -134,13 +134,13 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn position_at_end(&self, llbb: BasicBlockRef) { + pub fn position_at_end(&self, llbb: &'ll BasicBlock) { unsafe { llvm::LLVMPositionBuilderAtEnd(self.llbuilder, llbb); } } - pub fn position_at_start(&self, llbb: BasicBlockRef) { + pub fn position_at_start(&self, llbb: &'ll BasicBlock) { unsafe { llvm::LLVMRustPositionBuilderAtStart(self.llbuilder, llbb); } @@ -168,21 +168,21 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn br(&self, dest: BasicBlockRef) { + pub fn br(&self, dest: &'ll BasicBlock) { self.count_insn("br"); unsafe { llvm::LLVMBuildBr(self.llbuilder, dest); } } - pub fn cond_br(&self, cond: &'ll Value, then_llbb: BasicBlockRef, else_llbb: BasicBlockRef) { + pub fn cond_br(&self, cond: &'ll Value, then_llbb: &'ll BasicBlock, else_llbb: &'ll BasicBlock) { self.count_insn("condbr"); unsafe { llvm::LLVMBuildCondBr(self.llbuilder, cond, then_llbb, else_llbb); } } - pub fn switch(&self, v: &'ll Value, else_llbb: BasicBlockRef, num_cases: usize) -> &'ll Value { + pub fn switch(&self, v: &'ll Value, else_llbb: &'ll BasicBlock, num_cases: usize) -> &'ll Value { unsafe { llvm::LLVMBuildSwitch(self.llbuilder, v, else_llbb, num_cases as c_uint) } @@ -198,8 +198,8 @@ impl Builder<'a, 'll, 'tcx> { pub fn invoke(&self, llfn: &'ll Value, args: &[&'ll Value], - then: BasicBlockRef, - catch: BasicBlockRef, + then: &'ll BasicBlock, + catch: &'ll BasicBlock, bundle: Option<&OperandBundleDef>) -> &'ll Value { self.count_insn("invoke"); @@ -830,7 +830,7 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn phi(&self, ty: &'ll Type, vals: &[&'ll Value], bbs: &[BasicBlockRef]) -> &'ll Value { + pub fn phi(&self, ty: &'ll Type, vals: &[&'ll Value], bbs: &[&'ll BasicBlock]) -> &'ll Value { assert_eq!(vals.len(), bbs.len()); let phi = self.empty_phi(ty); self.count_insn("addincoming"); @@ -1167,10 +1167,11 @@ impl Builder<'a, 'll, 'tcx> { ret.expect("LLVM does not have support for cleanuppad") } - pub fn cleanup_ret(&self, cleanup: &'ll Value, - unwind: Option) -> &'ll Value { + pub fn cleanup_ret( + &self, cleanup: &'ll Value, + unwind: Option<&'ll BasicBlock>, + ) -> &'ll Value { self.count_insn("cleanupret"); - let unwind = unwind.and_then(NonNull::new); let ret = unsafe { llvm::LLVMRustBuildCleanupRet(self.llbuilder, cleanup, unwind) }; @@ -1190,7 +1191,7 @@ impl Builder<'a, 'll, 'tcx> { ret.expect("LLVM does not have support for catchpad") } - pub fn catch_ret(&self, pad: &'ll Value, unwind: BasicBlockRef) -> &'ll Value { + pub fn catch_ret(&self, pad: &'ll Value, unwind: &'ll BasicBlock) -> &'ll Value { self.count_insn("catchret"); let ret = unsafe { llvm::LLVMRustBuildCatchRet(self.llbuilder, pad, unwind) @@ -1201,11 +1202,10 @@ impl Builder<'a, 'll, 'tcx> { pub fn catch_switch( &self, parent: Option<&'ll Value>, - unwind: Option, + unwind: Option<&'ll BasicBlock>, num_handlers: usize, ) -> &'ll Value { self.count_insn("catchswitch"); - let unwind = unwind.and_then(NonNull::new); let name = CString::new("catchswitch").unwrap(); let ret = unsafe { llvm::LLVMRustBuildCatchSwitch(self.llbuilder, parent, unwind, @@ -1215,7 +1215,7 @@ impl Builder<'a, 'll, 'tcx> { ret.expect("LLVM does not have support for catchswitch") } - pub fn add_handler(&self, catch_switch: &'ll Value, handler: BasicBlockRef) { + pub fn add_handler(&self, catch_switch: &'ll Value, handler: &'ll BasicBlock) { unsafe { llvm::LLVMRustAddHandler(catch_switch, handler); } @@ -1260,13 +1260,13 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn add_case(&self, s: &'ll Value, on_val: &'ll Value, dest: BasicBlockRef) { + pub fn add_case(&self, s: &'ll Value, on_val: &'ll Value, dest: &'ll BasicBlock) { unsafe { llvm::LLVMAddCase(s, on_val, dest) } } - pub fn add_incoming_to_phi(&self, phi: &'ll Value, val: &'ll Value, bb: BasicBlockRef) { + pub fn add_incoming_to_phi(&self, phi: &'ll Value, val: &'ll Value, bb: &'ll BasicBlock) { self.count_insn("addincoming"); unsafe { llvm::LLVMAddIncoming(phi, &val, &bb, 1 as c_uint); diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index bf016bb8e3c6a..1b6014b495246 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -381,7 +381,6 @@ extern { pub type Type; } extern { pub type Value; } extern { pub type Metadata; } extern { pub type BasicBlock; } -pub type BasicBlockRef = *mut BasicBlock; extern { pub type Builder; } extern { pub type MemoryBuffer; } pub type MemoryBufferRef = *mut MemoryBuffer; @@ -716,18 +715,18 @@ extern "C" { pub fn LLVMGetParam(Fn: &Value, Index: c_uint) -> &Value; // Operations on basic blocks - pub fn LLVMBasicBlockAsValue(BB: BasicBlockRef) -> &'a Value; - pub fn LLVMGetBasicBlockParent(BB: BasicBlockRef) -> &'a Value; + pub fn LLVMBasicBlockAsValue(BB: &BasicBlock) -> &Value; + pub fn LLVMGetBasicBlockParent(BB: &BasicBlock) -> &Value; pub fn LLVMAppendBasicBlockInContext(C: &'a Context, Fn: &'a Value, Name: *const c_char) - -> BasicBlockRef; - pub fn LLVMDeleteBasicBlock(BB: BasicBlockRef); + -> &'a BasicBlock; + pub fn LLVMDeleteBasicBlock(BB: &BasicBlock); // Operations on instructions - pub fn LLVMGetInstructionParent(Inst: &Value) -> BasicBlockRef; - pub fn LLVMGetFirstBasicBlock(Fn: &Value) -> BasicBlockRef; - pub fn LLVMGetFirstInstruction(BB: BasicBlockRef) -> &'a Value; + pub fn LLVMGetInstructionParent(Inst: &Value) -> &BasicBlock; + pub fn LLVMGetFirstBasicBlock(Fn: &Value) -> &BasicBlock; + pub fn LLVMGetFirstInstruction(BB: &BasicBlock) -> &'a Value; pub fn LLVMInstructionEraseFromParent(Inst: &Value); // Operations on call sites @@ -745,15 +744,15 @@ extern "C" { // Operations on phi nodes pub fn LLVMAddIncoming(PhiNode: &'a Value, IncomingValues: *const &'a Value, - IncomingBlocks: *const BasicBlockRef, + IncomingBlocks: *const &'a BasicBlock, Count: c_uint); // Instruction builders pub fn LLVMCreateBuilderInContext(C: &Context) -> &Builder; - pub fn LLVMPositionBuilder(Builder: &'a Builder, Block: BasicBlockRef, Instr: &'a Value); + pub fn LLVMPositionBuilder(Builder: &'a Builder, Block: &'a BasicBlock, Instr: &'a Value); pub fn LLVMPositionBuilderBefore(Builder: &'a Builder, Instr: &'a Value); - pub fn LLVMPositionBuilderAtEnd(Builder: &Builder, Block: BasicBlockRef); - pub fn LLVMGetInsertBlock(Builder: &Builder) -> BasicBlockRef; + pub fn LLVMPositionBuilderAtEnd(Builder: &'a Builder, Block: &'a BasicBlock); + pub fn LLVMGetInsertBlock(Builder: &Builder) -> &BasicBlock; pub fn LLVMDisposeBuilder(Builder: &Builder); // Metadata @@ -765,15 +764,15 @@ extern "C" { pub fn LLVMBuildRetVoid(B: &Builder) -> &Value; pub fn LLVMBuildRet(B: &'a Builder, V: &'a Value) -> &'a Value; pub fn LLVMBuildAggregateRet(B: &'a Builder, RetVals: *const &'a Value, N: c_uint) -> &'a Value; - pub fn LLVMBuildBr(B: &Builder, Dest: BasicBlockRef) -> &Value; + pub fn LLVMBuildBr(B: &'a Builder, Dest: &'a BasicBlock) -> &'a Value; pub fn LLVMBuildCondBr(B: &'a Builder, If: &'a Value, - Then: BasicBlockRef, - Else: BasicBlockRef) + Then: &'a BasicBlock, + Else: &'a BasicBlock) -> &'a Value; pub fn LLVMBuildSwitch(B: &'a Builder, V: &'a Value, - Else: BasicBlockRef, + Else: &'a BasicBlock, NumCases: c_uint) -> &'a Value; pub fn LLVMBuildIndirectBr(B: &'a Builder, Addr: &'a Value, NumDests: c_uint) -> &'a Value; @@ -781,8 +780,8 @@ extern "C" { Fn: &'a Value, Args: *const &'a Value, NumArgs: c_uint, - Then: BasicBlockRef, - Catch: BasicBlockRef, + Then: &'a BasicBlock, + Catch: &'a BasicBlock, Bundle: Option>, Name: *const c_char) -> &'a Value; @@ -803,7 +802,7 @@ extern "C" { -> Option<&'a Value>; pub fn LLVMRustBuildCleanupRet(B: &'a Builder, CleanupPad: &'a Value, - UnwindBB: Option>) + UnwindBB: Option<&'a BasicBlock>) -> Option<&'a Value>; pub fn LLVMRustBuildCatchPad(B: &'a Builder, ParentPad: &'a Value, @@ -811,18 +810,18 @@ extern "C" { Args: *const &'a Value, Name: *const c_char) -> Option<&'a Value>; - pub fn LLVMRustBuildCatchRet(B: &'a Builder, Pad: &'a Value, BB: BasicBlockRef) -> Option<&'a Value>; + pub fn LLVMRustBuildCatchRet(B: &'a Builder, Pad: &'a Value, BB: &'a BasicBlock) -> Option<&'a Value>; pub fn LLVMRustBuildCatchSwitch(Builder: &'a Builder, ParentPad: Option<&'a Value>, - BB: Option>, + BB: Option<&'a BasicBlock>, NumHandlers: c_uint, Name: *const c_char) -> Option<&'a Value>; - pub fn LLVMRustAddHandler(CatchSwitch: &Value, Handler: BasicBlockRef); + pub fn LLVMRustAddHandler(CatchSwitch: &'a Value, Handler: &'a BasicBlock); pub fn LLVMSetPersonalityFn(Func: &'a Value, Pers: &'a Value); // Add a case to the switch instruction - pub fn LLVMAddCase(Switch: &'a Value, OnVal: &'a Value, Dest: BasicBlockRef); + pub fn LLVMAddCase(Switch: &'a Value, OnVal: &'a Value, Dest: &'a BasicBlock); // Add a clause to the landing pad instruction pub fn LLVMAddClause(LandingPad: &'a Value, ClauseVal: &'a Value); @@ -1503,7 +1502,7 @@ extern "C" { AddrOps: *const i64, AddrOpsCount: c_uint, DL: &'a Value, - InsertAtEnd: BasicBlockRef) + InsertAtEnd: &'a BasicBlock) -> &'a Value; pub fn LLVMRustDIBuilderCreateEnumerator(Builder: &DIBuilder, @@ -1691,7 +1690,7 @@ extern "C" { -> OperandBundleDefRef; pub fn LLVMRustFreeOperandBundleDef(Bundle: OperandBundleDefRef); - pub fn LLVMRustPositionBuilderAtStart(B: &Builder, BB: BasicBlockRef); + pub fn LLVMRustPositionBuilderAtStart(B: &'a Builder, BB: &'a BasicBlock); pub fn LLVMRustSetComdat(M: &'a Module, V: &'a Value, Name: *const c_char); pub fn LLVMRustUnsetComdat(V: &Value); diff --git a/src/librustc_codegen_llvm/mir/block.rs b/src/librustc_codegen_llvm/mir/block.rs index 587165dfe77f2..684ecfaeec8f1 100644 --- a/src/librustc_codegen_llvm/mir/block.rs +++ b/src/librustc_codegen_llvm/mir/block.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use llvm::{self, BasicBlockRef}; +use llvm::{self, BasicBlock}; use rustc::middle::lang_items; use rustc::ty::{self, Ty, TypeFoldable}; use rustc::ty::layout::{self, LayoutOf}; @@ -754,7 +754,7 @@ impl FunctionCx<'a, 'll, 'tcx> { /// Return the landingpad wrapper around the given basic block /// /// No-op in MSVC SEH scheme. - fn landing_pad_to(&mut self, target_bb: mir::BasicBlock) -> BasicBlockRef { + fn landing_pad_to(&mut self, target_bb: mir::BasicBlock) -> &'ll BasicBlock { if let Some(block) = self.landing_pads[target_bb] { return block; } @@ -765,7 +765,7 @@ impl FunctionCx<'a, 'll, 'tcx> { landing_pad } - fn landing_pad_uncached(&mut self, target_bb: BasicBlockRef) -> BasicBlockRef { + fn landing_pad_uncached(&mut self, target_bb: &'ll BasicBlock) -> &'ll BasicBlock { if base::wants_msvc_seh(self.cx.sess()) { span_bug!(self.mir.span, "landing pad was not inserted?") } @@ -790,7 +790,7 @@ impl FunctionCx<'a, 'll, 'tcx> { Type::struct_(cx, &[Type::i8p(cx), Type::i32(cx)], false) } - fn unreachable_block(&mut self) -> BasicBlockRef { + fn unreachable_block(&mut self) -> &'ll BasicBlock { self.unreachable_block.unwrap_or_else(|| { let bl = self.new_block("unreachable"); bl.unreachable(); diff --git a/src/librustc_codegen_llvm/mir/mod.rs b/src/librustc_codegen_llvm/mir/mod.rs index be9cd005013f7..8cdd0398eff96 100644 --- a/src/librustc_codegen_llvm/mir/mod.rs +++ b/src/librustc_codegen_llvm/mir/mod.rs @@ -10,7 +10,7 @@ use common::{C_i32, C_null}; use libc::c_uint; -use llvm::{self, BasicBlockRef}; +use llvm::{self, BasicBlock}; use llvm::debuginfo::DIScope; use rustc::ty::{self, Ty, TypeFoldable, UpvarSubsts}; use rustc::ty::layout::{LayoutOf, TyLayout}; @@ -66,7 +66,7 @@ pub struct FunctionCx<'a, 'll: 'a, 'tcx: 'll> { personality_slot: Option>, /// A `Block` for each MIR `BasicBlock` - blocks: IndexVec, + blocks: IndexVec, /// The funclet status of each basic block cleanup_kinds: IndexVec, @@ -77,10 +77,10 @@ pub struct FunctionCx<'a, 'll: 'a, 'tcx: 'll> { /// This stores the landing-pad block for a given BB, computed lazily on GNU /// and eagerly on MSVC. - landing_pads: IndexVec>, + landing_pads: IndexVec>, /// Cached unreachable block - unreachable_block: Option, + unreachable_block: Option<&'ll BasicBlock>, /// The location where each MIR arg/var/tmp/ret is stored. This is /// usually an `PlaceRef` representing an alloca, but not always: @@ -219,7 +219,7 @@ pub fn codegen_mir( // Allocate a `Block` for every basic block, except // the start block, if nothing loops back to it. let reentrant_start_block = !mir.predecessors_for(mir::START_BLOCK).is_empty(); - let block_bxs: IndexVec = + let block_bxs: IndexVec = mir.basic_blocks().indices().map(|bb| { if bb == mir::START_BLOCK && !reentrant_start_block { bx.llbb() @@ -348,8 +348,8 @@ fn create_funclets( mir: &'a Mir<'tcx>, bx: &Builder<'a, 'll, 'tcx>, cleanup_kinds: &IndexVec, - block_bxs: &IndexVec) - -> (IndexVec>, + block_bxs: &IndexVec) + -> (IndexVec>, IndexVec>>) { block_bxs.iter_enumerated().zip(cleanup_kinds).map(|((bb, &llbb), cleanup_kind)| { From f224441ed5a6542c496e826088a99944d5963cbf Mon Sep 17 00:00:00 2001 From: Irina Popa Date: Tue, 10 Jul 2018 14:37:52 +0300 Subject: [PATCH 13/36] rustc_codegen_llvm: remove unused UseRef type. --- src/librustc_codegen_llvm/llvm/ffi.rs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index 1b6014b495246..d6b6d07680700 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -388,8 +388,6 @@ extern { pub type PassManager; } pub type PassManagerRef = *mut PassManager; extern { pub type PassManagerBuilder; } pub type PassManagerBuilderRef = *mut PassManagerBuilder; -extern { pub type Use; } -pub type UseRef = *mut Use; extern { pub type ObjectFile; } pub type ObjectFileRef = *mut ObjectFile; extern { pub type SectionIterator; } @@ -556,11 +554,6 @@ extern "C" { pub fn LLVMReplaceAllUsesWith(OldVal: &'a Value, NewVal: &'a Value); pub fn LLVMSetMetadata(Val: &'a Value, KindID: c_uint, Node: &'a Value); - // Operations on Uses - pub fn LLVMGetFirstUse(Val: &Value) -> UseRef; - pub fn LLVMGetNextUse(U: UseRef) -> UseRef; - pub fn LLVMGetUser(U: UseRef) -> &'a Value; - // Operations on Users pub fn LLVMGetOperand(Val: &Value, Index: c_uint) -> &Value; From ebec156abfc25ce695227ed2c12c420244a433f8 Mon Sep 17 00:00:00 2001 From: Irina Popa Date: Tue, 10 Jul 2018 18:00:02 +0300 Subject: [PATCH 14/36] rustc_codegen_llvm: remove more unused functions. --- src/librustc_codegen_llvm/builder.rs | 194 +------------------------ src/librustc_codegen_llvm/llvm/ffi.rs | 195 +++----------------------- src/rustllvm/PassWrapper.cpp | 24 ---- src/rustllvm/RustWrapper.cpp | 9 -- 4 files changed, 21 insertions(+), 401 deletions(-) diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index dbc16cbbf0ded..676523b09f772 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -8,10 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![allow(dead_code)] // FFI wrappers - use llvm::{AtomicRmwBinOp, AtomicOrdering, SynchronizationScope, AsmDialect}; -use llvm::{Opcode, IntPredicate, RealPredicate, False, OperandBundleDef}; +use llvm::{IntPredicate, RealPredicate, False, OperandBundleDef}; use llvm::{self, BasicBlock}; use common::*; use type_::Type; @@ -26,7 +24,6 @@ use std::ffi::CString; use std::ops::Range; use std::ptr; use std::ptr::NonNull; -use syntax_pos::Span; // All Builders must have an llfn associated with them #[must_use] @@ -128,12 +125,6 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn position_before(&self, insn: &'ll Value) { - unsafe { - llvm::LLVMPositionBuilderBefore(self.llbuilder, insn); - } - } - pub fn position_at_end(&self, llbb: &'ll BasicBlock) { unsafe { llvm::LLVMPositionBuilderAtEnd(self.llbuilder, llbb); @@ -160,14 +151,6 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn aggregate_ret(&self, ret_vals: &[&'ll Value]) { - unsafe { - llvm::LLVMBuildAggregateRet(self.llbuilder, - ret_vals.as_ptr(), - ret_vals.len() as c_uint); - } - } - pub fn br(&self, dest: &'ll BasicBlock) { self.count_insn("br"); unsafe { @@ -188,13 +171,6 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn indirect_br(&self, addr: &'ll Value, num_dests: usize) { - self.count_insn("indirectbr"); - unsafe { - llvm::LLVMBuildIndirectBr(self.llbuilder, addr, num_dests as c_uint); - } - } - pub fn invoke(&self, llfn: &'ll Value, args: &[&'ll Value], @@ -237,20 +213,6 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn nswadd(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { - self.count_insn("nswadd"); - unsafe { - llvm::LLVMBuildNSWAdd(self.llbuilder, lhs, rhs, noname()) - } - } - - pub fn nuwadd(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { - self.count_insn("nuwadd"); - unsafe { - llvm::LLVMBuildNUWAdd(self.llbuilder, lhs, rhs, noname()) - } - } - pub fn fadd(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { self.count_insn("fadd"); unsafe { @@ -274,20 +236,6 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn nswsub(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { - self.count_insn("nswsub"); - unsafe { - llvm::LLVMBuildNSWSub(self.llbuilder, lhs, rhs, noname()) - } - } - - pub fn nuwsub(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { - self.count_insn("nuwsub"); - unsafe { - llvm::LLVMBuildNUWSub(self.llbuilder, lhs, rhs, noname()) - } - } - pub fn fsub(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { self.count_insn("fsub"); unsafe { @@ -311,20 +259,6 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn nswmul(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { - self.count_insn("nswmul"); - unsafe { - llvm::LLVMBuildNSWMul(self.llbuilder, lhs, rhs, noname()) - } - } - - pub fn nuwmul(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { - self.count_insn("nuwmul"); - unsafe { - llvm::LLVMBuildNUWMul(self.llbuilder, lhs, rhs, noname()) - } - } - pub fn fmul(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { self.count_insn("fmul"); unsafe { @@ -458,14 +392,6 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn binop(&self, op: Opcode, lhs: &'ll Value, rhs: &'ll Value) - -> &'ll Value { - self.count_insn("binop"); - unsafe { - llvm::LLVMBuildBinOp(self.llbuilder, op, lhs, rhs, noname()) - } - } - pub fn neg(&self, v: &'ll Value) -> &'ll Value { self.count_insn("neg"); unsafe { @@ -473,19 +399,6 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn nswneg(&self, v: &'ll Value) -> &'ll Value { - self.count_insn("nswneg"); - unsafe { - llvm::LLVMBuildNSWNeg(self.llbuilder, v, noname()) - } - } - - pub fn nuwneg(&self, v: &'ll Value) -> &'ll Value { - self.count_insn("nuwneg"); - unsafe { - llvm::LLVMBuildNUWNeg(self.llbuilder, v, noname()) - } - } pub fn fneg(&self, v: &'ll Value) -> &'ll Value { self.count_insn("fneg"); unsafe { @@ -523,13 +436,6 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn free(&self, ptr: &'ll Value) { - self.count_insn("free"); - unsafe { - llvm::LLVMBuildFree(self.llbuilder, ptr); - } - } - pub fn load(&self, ptr: &'ll Value, align: Align) -> &'ll Value { self.count_insn("load"); unsafe { @@ -658,20 +564,6 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn global_string(&self, _str: *const c_char) -> &'ll Value { - self.count_insn("globalstring"); - unsafe { - llvm::LLVMBuildGlobalString(self.llbuilder, _str, noname()) - } - } - - pub fn global_string_ptr(&self, _str: *const c_char) -> &'ll Value { - self.count_insn("globalstringptr"); - unsafe { - llvm::LLVMBuildGlobalStringPtr(self.llbuilder, _str, noname()) - } - } - /* Casts */ pub fn trunc(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { self.count_insn("trunc"); @@ -757,34 +649,6 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn zext_or_bitcast(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { - self.count_insn("zextorbitcast"); - unsafe { - llvm::LLVMBuildZExtOrBitCast(self.llbuilder, val, dest_ty, noname()) - } - } - - pub fn sext_or_bitcast(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { - self.count_insn("sextorbitcast"); - unsafe { - llvm::LLVMBuildSExtOrBitCast(self.llbuilder, val, dest_ty, noname()) - } - } - - pub fn trunc_or_bitcast(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { - self.count_insn("truncorbitcast"); - unsafe { - llvm::LLVMBuildTruncOrBitCast(self.llbuilder, val, dest_ty, noname()) - } - } - - pub fn cast(&self, op: Opcode, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { - self.count_insn("cast"); - unsafe { - llvm::LLVMBuildCast(self.llbuilder, op, val, dest_ty, noname()) - } - } - pub fn pointercast(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { self.count_insn("pointercast"); unsafe { @@ -799,14 +663,6 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn fpcast(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { - self.count_insn("fpcast"); - unsafe { - llvm::LLVMBuildFPCast(self.llbuilder, val, dest_ty, noname()) - } - } - - /* Comparisons */ pub fn icmp(&self, op: IntPredicate, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { self.count_insn("icmp"); @@ -842,32 +698,6 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn add_span_comment(&self, sp: Span, text: &str) { - if self.cx.sess().asm_comments() { - let s = format!("{} ({})", - text, - self.cx.sess().codemap().span_to_string(sp)); - debug!("{}", s); - self.add_comment(&s); - } - } - - pub fn add_comment(&self, text: &str) { - if self.cx.sess().asm_comments() { - let sanitized = text.replace("$", ""); - let comment_text = format!("{} {}", "#", - sanitized.replace("\n", "\n\t# ")); - self.count_insn("inlineasm"); - let comment_text = CString::new(comment_text).unwrap(); - let asm = unsafe { - llvm::LLVMConstInlineAsm(Type::func(&[], Type::void(self.cx)), - comment_text.as_ptr(), noname(), False, - False) - }; - self.call(asm, &[], None); - } - } - pub fn inline_asm_call(&self, asm: *const c_char, cons: *const c_char, inputs: &[&'ll Value], output: &'ll Type, volatile: bool, alignstack: bool, @@ -936,6 +766,7 @@ impl Builder<'a, 'll, 'tcx> { } } + #[allow(dead_code)] pub fn va_arg(&self, list: &'ll Value, ty: &'ll Type) -> &'ll Value { self.count_insn("vaarg"); unsafe { @@ -1102,27 +933,6 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn is_null(&self, val: &'ll Value) -> &'ll Value { - self.count_insn("isnull"); - unsafe { - llvm::LLVMBuildIsNull(self.llbuilder, val, noname()) - } - } - - pub fn is_not_null(&self, val: &'ll Value) -> &'ll Value { - self.count_insn("isnotnull"); - unsafe { - llvm::LLVMBuildIsNotNull(self.llbuilder, val, noname()) - } - } - - pub fn ptrdiff(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { - self.count_insn("ptrdiff"); - unsafe { - llvm::LLVMBuildPtrDiff(self.llbuilder, lhs, rhs, noname()) - } - } - pub fn landing_pad(&self, ty: &'ll Type, pers_fn: &'ll Value, num_clauses: usize) -> &'ll Value { self.count_insn("landingpad"); diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index d6b6d07680700..d67cc773bbcc8 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -22,13 +22,12 @@ use super::debuginfo::{ }; use libc::{c_uint, c_int, size_t, c_char}; -use libc::{c_longlong, c_ulonglong, c_void}; +use libc::{c_ulonglong, c_void}; use std::ptr::NonNull; use super::RustStringRef; -pub type Opcode = u32; pub type Bool = c_uint; pub const True: Bool = 1 as Bool; @@ -36,6 +35,7 @@ pub const False: Bool = 0 as Bool; #[derive(Copy, Clone, PartialEq)] #[repr(C)] +#[allow(dead_code)] // Variants constructed by C++. pub enum LLVMRustResult { Success, Failure, @@ -88,22 +88,14 @@ pub enum Visibility { 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 { + #[allow(dead_code)] Default = 0, DllImport = 1, // Function to be imported from DLL. + #[allow(dead_code)] DllExport = 2, // Function to be accessible from DLL. } @@ -220,6 +212,7 @@ pub enum AtomicRmwBinOp { #[derive(Copy, Clone)] #[repr(C)] pub enum AtomicOrdering { + #[allow(dead_code)] NotAtomic = 0, Unordered = 1, Monotonic = 2, @@ -234,6 +227,8 @@ pub enum AtomicOrdering { #[derive(Copy, Clone)] #[repr(C)] pub enum SynchronizationScope { + // FIXME: figure out if this variant is needed at all. + #[allow(dead_code)] Other, SingleThread, CrossThread, @@ -243,6 +238,8 @@ pub enum SynchronizationScope { #[derive(Copy, Clone)] #[repr(C)] pub enum FileType { + // FIXME: figure out if this variant is needed at all. + #[allow(dead_code)] Other, AssemblyFile, ObjectFile, @@ -270,6 +267,8 @@ pub enum MetadataType { #[derive(Copy, Clone)] #[repr(C)] pub enum AsmDialect { + // FIXME: figure out if this variant is needed at all. + #[allow(dead_code)] Other, Att, Intel, @@ -279,6 +278,8 @@ pub enum AsmDialect { #[derive(Copy, Clone, PartialEq)] #[repr(C)] pub enum CodeGenOptLevel { + // FIXME: figure out if this variant is needed at all. + #[allow(dead_code)] Other, None, Less, @@ -303,6 +304,8 @@ pub enum RelocMode { #[derive(Copy, Clone)] #[repr(C)] pub enum CodeModel { + // FIXME: figure out if this variant is needed at all. + #[allow(dead_code)] Other, Small, Kernel, @@ -314,6 +317,7 @@ pub enum CodeModel { /// LLVMRustDiagnosticKind #[derive(Copy, Clone)] #[repr(C)] +#[allow(dead_code)] // Variants constructed by C++. pub enum DiagnosticKind { Other, InlineAsm, @@ -334,6 +338,8 @@ pub enum DiagnosticKind { #[derive(Copy, Clone)] #[repr(C)] pub enum ArchiveKind { + // FIXME: figure out if this variant is needed at all. + #[allow(dead_code)] Other, K_GNU, K_BSD, @@ -343,6 +349,7 @@ pub enum ArchiveKind { /// LLVMRustPassKind #[derive(Copy, Clone, PartialEq, Debug)] #[repr(C)] +#[allow(dead_code)] // Variants constructed by C++. pub enum PassKind { Other, Function, @@ -406,8 +413,6 @@ extern { pub type Twine; } pub type TwineRef = *mut Twine; extern { pub type DiagnosticInfo; } pub type DiagnosticInfoRef = *mut DiagnosticInfo; -extern { pub type DebugLoc; } -pub type DebugLocRef = *mut DebugLoc; extern { pub type SMDiagnostic; } pub type SMDiagnosticRef = *mut SMDiagnostic; extern { pub type RustArchiveMember; } @@ -492,9 +497,6 @@ extern "C" { pub fn LLVMGetDataLayout(M: &Module) -> *const c_char; pub fn LLVMSetDataLayout(M: &Module, Triple: *const c_char); - /// See Module::dump. - pub fn LLVMDumpModule(M: &Module); - /// See Module::setModuleInlineAsm. pub fn LLVMSetModuleInlineAsm(M: &Module, Asm: *const c_char); pub fn LLVMRustAppendModuleInlineAsm(M: &Module, Asm: *const c_char); @@ -522,7 +524,6 @@ extern "C" { ParamCount: c_uint, IsVarArg: Bool) -> &'a Type; - pub fn LLVMGetReturnType(FunctionTy: &Type) -> &Type; pub fn LLVMCountParamTypes(FunctionTy: &Type) -> c_uint; pub fn LLVMGetParamTypes(FunctionTy: &'a Type, Dest: *mut &'a Type); @@ -532,7 +533,6 @@ extern "C" { ElementCount: c_uint, Packed: Bool) -> &'a Type; - pub fn LLVMIsPackedStruct(StructTy: &Type) -> Bool; // Operations on array, pointer, and vector types (sequence types) pub fn LLVMRustArrayType(ElementType: &Type, ElementCount: u64) -> &Type; @@ -554,13 +554,8 @@ extern "C" { pub fn LLVMReplaceAllUsesWith(OldVal: &'a Value, NewVal: &'a Value); pub fn LLVMSetMetadata(Val: &'a Value, KindID: c_uint, Node: &'a Value); - // Operations on Users - pub fn LLVMGetOperand(Val: &Value, Index: c_uint) -> &Value; - // Operations on constants of any type pub fn LLVMConstNull(Ty: &Type) -> &Value; - pub fn LLVMConstICmp(Pred: IntPredicate, V1: &'a Value, V2: &'a Value) -> &'a Value; - pub fn LLVMConstFCmp(Pred: RealPredicate, V1: &'a Value, V2: &'a Value) -> &'a Value; pub fn LLVMGetUndef(Ty: &Type) -> &Value; // Operations on metadata @@ -572,7 +567,6 @@ extern "C" { pub fn LLVMConstInt(IntTy: &Type, N: c_ulonglong, SignExtend: Bool) -> &Value; pub fn LLVMConstIntOfArbitraryPrecision(IntTy: &Type, Wn: c_uint, Ws: *const u64) -> &Value; pub fn LLVMConstIntGetZExtValue(ConstantVal: &Value) -> c_ulonglong; - pub fn LLVMConstIntGetSExtValue(ConstantVal: &Value) -> c_longlong; pub fn LLVMRustConstInt128Get(ConstantVal: &Value, SExt: bool, high: *mut u64, low: *mut u64) -> bool; pub fn LLVMConstRealGetDouble (ConstantVal: &Value, losesInfo: *mut Bool) -> f64; @@ -597,67 +591,25 @@ extern "C" { pub fn LLVMConstVector(ScalarConstantVals: *const &Value, Size: c_uint) -> &Value; // Constant expressions - pub fn LLVMSizeOf(Ty: &Type) -> &Value; - pub fn LLVMConstNeg(ConstantVal: &Value) -> &Value; - pub fn LLVMConstFNeg(ConstantVal: &Value) -> &Value; - pub fn LLVMConstNot(ConstantVal: &Value) -> &Value; - pub fn LLVMConstAdd(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - pub fn LLVMConstFAdd(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - pub fn LLVMConstSub(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - pub fn LLVMConstFSub(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - pub fn LLVMConstMul(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - pub fn LLVMConstFMul(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - pub fn LLVMConstUDiv(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - pub fn LLVMConstSDiv(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - pub fn LLVMConstFDiv(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - pub fn LLVMConstURem(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - pub fn LLVMConstSRem(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - pub fn LLVMConstFRem(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - pub fn LLVMConstAnd(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - pub fn LLVMConstOr(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - pub fn LLVMConstXor(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - pub fn LLVMConstShl(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - pub fn LLVMConstLShr(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - pub fn LLVMConstAShr(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - pub fn LLVMConstGEP( - ConstantVal: &'a Value, - ConstantIndices: *const &'a Value, - NumIndices: c_uint, - ) -> &'a Value; pub fn LLVMConstInBoundsGEP( ConstantVal: &'a Value, ConstantIndices: *const &'a Value, NumIndices: c_uint, ) -> &'a Value; - pub fn LLVMConstTrunc(ConstantVal: &'a Value, ToType: &'a Type) -> &'a Value; pub fn LLVMConstZExt(ConstantVal: &'a Value, ToType: &'a Type) -> &'a Value; - pub fn LLVMConstUIToFP(ConstantVal: &'a Value, ToType: &'a Type) -> &'a Value; - pub fn LLVMConstSIToFP(ConstantVal: &'a Value, ToType: &'a Type) -> &'a Value; - pub fn LLVMConstFPToUI(ConstantVal: &'a Value, ToType: &'a Type) -> &'a Value; - pub fn LLVMConstFPToSI(ConstantVal: &'a Value, ToType: &'a Type) -> &'a Value; pub fn LLVMConstPtrToInt(ConstantVal: &'a Value, ToType: &'a Type) -> &'a Value; pub fn LLVMConstIntToPtr(ConstantVal: &'a Value, ToType: &'a Type) -> &'a Value; pub fn LLVMConstBitCast(ConstantVal: &'a Value, ToType: &'a Type) -> &'a Value; pub fn LLVMConstPointerCast(ConstantVal: &'a Value, ToType: &'a Type) -> &'a Value; - pub fn LLVMConstIntCast(ConstantVal: &'a Value, ToType: &'a Type, isSigned: Bool) -> &'a Value; - pub fn LLVMConstFPCast(ConstantVal: &'a Value, ToType: &'a Type) -> &'a Value; pub fn LLVMConstExtractValue(AggConstant: &Value, IdxList: *const c_uint, NumIdx: c_uint) -> &Value; - pub fn LLVMConstInlineAsm(Ty: &Type, - AsmString: *const c_char, - Constraints: *const c_char, - HasSideEffects: Bool, - IsAlignStack: Bool) - -> &Value; - // Operations on global variables, functions, and aliases (globals) pub fn LLVMIsDeclaration(Global: &Value) -> Bool; pub fn LLVMRustGetLinkage(Global: &Value) -> Linkage; pub fn LLVMRustSetLinkage(Global: &Value, RustLinkage: Linkage); - pub fn LLVMGetSection(Global: &Value) -> *const c_char; pub fn LLVMSetSection(Global: &Value, Section: *const c_char); pub fn LLVMRustGetVisibility(Global: &Value) -> Visibility; pub fn LLVMRustSetVisibility(Global: &Value, Viz: Visibility); @@ -684,10 +636,6 @@ extern "C" { pub fn LLVMSetTailCall(CallInst: &Value, IsTailCall: Bool); // Operations on functions - pub fn LLVMAddFunction(M: &'a Module, Name: *const c_char, FunctionTy: &'a Type) -> &'a Value; - pub fn LLVMGetNamedFunction(M: &Module, Name: *const c_char) -> &Value; - pub fn LLVMGetFirstFunction(M: &Module) -> &Value; - pub fn LLVMGetNextFunction(Fn: &Value) -> &Value; pub fn LLVMRustGetOrInsertFunction(M: &'a Module, Name: *const c_char, FunctionTy: &'a Type) @@ -708,7 +656,6 @@ extern "C" { pub fn LLVMGetParam(Fn: &Value, Index: c_uint) -> &Value; // Operations on basic blocks - pub fn LLVMBasicBlockAsValue(BB: &BasicBlock) -> &Value; pub fn LLVMGetBasicBlockParent(BB: &BasicBlock) -> &Value; pub fn LLVMAppendBasicBlockInContext(C: &'a Context, Fn: &'a Value, @@ -717,10 +664,7 @@ extern "C" { pub fn LLVMDeleteBasicBlock(BB: &BasicBlock); // Operations on instructions - pub fn LLVMGetInstructionParent(Inst: &Value) -> &BasicBlock; pub fn LLVMGetFirstBasicBlock(Fn: &Value) -> &BasicBlock; - pub fn LLVMGetFirstInstruction(BB: &BasicBlock) -> &'a Value; - pub fn LLVMInstructionEraseFromParent(Inst: &Value); // Operations on call sites pub fn LLVMSetInstructionCallConv(Instr: &Value, CC: c_uint); @@ -742,8 +686,6 @@ extern "C" { // Instruction builders pub fn LLVMCreateBuilderInContext(C: &Context) -> &Builder; - pub fn LLVMPositionBuilder(Builder: &'a Builder, Block: &'a BasicBlock, Instr: &'a Value); - pub fn LLVMPositionBuilderBefore(Builder: &'a Builder, Instr: &'a Value); pub fn LLVMPositionBuilderAtEnd(Builder: &'a Builder, Block: &'a BasicBlock); pub fn LLVMGetInsertBlock(Builder: &Builder) -> &BasicBlock; pub fn LLVMDisposeBuilder(Builder: &Builder); @@ -756,7 +698,6 @@ extern "C" { // Terminators pub fn LLVMBuildRetVoid(B: &Builder) -> &Value; pub fn LLVMBuildRet(B: &'a Builder, V: &'a Value) -> &'a Value; - pub fn LLVMBuildAggregateRet(B: &'a Builder, RetVals: *const &'a Value, N: c_uint) -> &'a Value; pub fn LLVMBuildBr(B: &'a Builder, Dest: &'a BasicBlock) -> &'a Value; pub fn LLVMBuildCondBr(B: &'a Builder, If: &'a Value, @@ -768,7 +709,6 @@ extern "C" { Else: &'a BasicBlock, NumCases: c_uint) -> &'a Value; - pub fn LLVMBuildIndirectBr(B: &'a Builder, Addr: &'a Value, NumDests: c_uint) -> &'a Value; pub fn LLVMRustBuildInvoke(B: &'a Builder, Fn: &'a Value, Args: *const &'a Value, @@ -828,16 +768,6 @@ extern "C" { RHS: &'a Value, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildNSWAdd(B: &'a Builder, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildNUWAdd(B: &'a Builder, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char) - -> &'a Value; pub fn LLVMBuildFAdd(B: &'a Builder, LHS: &'a Value, RHS: &'a Value, @@ -848,16 +778,6 @@ extern "C" { RHS: &'a Value, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildNSWSub(B: &'a Builder, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildNUWSub(B: &'a Builder, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char) - -> &'a Value; pub fn LLVMBuildFSub(B: &'a Builder, LHS: &'a Value, RHS: &'a Value, @@ -868,16 +788,6 @@ extern "C" { RHS: &'a Value, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildNSWMul(B: &'a Builder, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildNUWMul(B: &'a Builder, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char) - -> &'a Value; pub fn LLVMBuildFMul(B: &'a Builder, LHS: &'a Value, RHS: &'a Value, @@ -953,22 +863,13 @@ extern "C" { RHS: &'a Value, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildBinOp(B: &'a Builder, - Op: Opcode, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char) - -> &'a Value; pub fn LLVMBuildNeg(B: &'a Builder, V: &'a Value, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildNSWNeg(B: &'a Builder, V: &'a Value, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildNUWNeg(B: &'a Builder, V: &'a Value, Name: *const c_char) -> &'a Value; pub fn LLVMBuildFNeg(B: &'a Builder, V: &'a Value, Name: *const c_char) -> &'a Value; pub fn LLVMBuildNot(B: &'a Builder, V: &'a Value, Name: *const c_char) -> &'a Value; pub fn LLVMRustSetHasUnsafeAlgebra(Instr: &Value); // Memory pub fn LLVMBuildAlloca(B: &'a Builder, Ty: &'a Type, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildFree(B: &'a Builder, PointerVal: &'a Value) -> &'a Value; pub fn LLVMBuildLoad(B: &'a Builder, PointerVal: &'a Value, Name: *const c_char) -> &'a Value; pub fn LLVMBuildStore(B: &'a Builder, Val: &'a Value, Ptr: &'a Value) -> &'a Value; @@ -990,14 +891,6 @@ extern "C" { Idx: c_uint, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildGlobalString(B: &Builder, - Str: *const c_char, - Name: *const c_char) - -> &Value; - pub fn LLVMBuildGlobalStringPtr(B: &Builder, - Str: *const c_char, - Name: *const c_char) - -> &Value; // Casts pub fn LLVMBuildTrunc(B: &'a Builder, @@ -1060,27 +953,6 @@ extern "C" { DestTy: &'a Type, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildZExtOrBitCast(B: &'a Builder, - Val: &'a Value, - DestTy: &'a Type, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildSExtOrBitCast(B: &'a Builder, - Val: &'a Value, - DestTy: &'a Type, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildTruncOrBitCast(B: &'a Builder, - Val: &'a Value, - DestTy: &'a Type, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildCast(B: &'a Builder, - Op: Opcode, - Val: &'a Value, - DestTy: &'a Type, - Name: *const c_char) - -> &'a Value; pub fn LLVMBuildPointerCast(B: &'a Builder, Val: &'a Value, DestTy: &'a Type, @@ -1091,11 +963,6 @@ extern "C" { DestTy: &'a Type, IsSized: bool) -> &'a Value; - pub fn LLVMBuildFPCast(B: &'a Builder, - Val: &'a Value, - DestTy: &'a Type, - Name: *const c_char) - -> &'a Value; // Comparisons pub fn LLVMBuildICmp(B: &'a Builder, @@ -1203,14 +1070,6 @@ extern "C" { pub fn LLVMRustBuildMinNum(B: &'a Builder, LHS: &'a Value, LHS: &'a Value) -> Option<&'a Value>; pub fn LLVMRustBuildMaxNum(B: &'a Builder, LHS: &'a Value, LHS: &'a Value) -> Option<&'a Value>; - pub fn LLVMBuildIsNull(B: &'a Builder, Val: &'a Value, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildIsNotNull(B: &'a Builder, Val: &'a Value, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildPtrDiff(B: &'a Builder, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char) - -> &'a Value; - // Atomic Operations pub fn LLVMRustBuildAtomicLoad(B: &'a Builder, PointerVal: &'a Value, @@ -1245,11 +1104,6 @@ extern "C" { Order: AtomicOrdering, Scope: SynchronizationScope); - - // Selected entries from the downcasts. - pub fn LLVMIsATerminatorInst(Inst: &Value) -> &Value; - pub fn LLVMIsAStoreInst(Inst: &Value) -> &Value; - /// Writes a module to the specified path. Returns 0 on success. pub fn LLVMWriteBitcodeToFile(M: &Module, Path: *const c_char) -> c_int; @@ -1472,13 +1326,6 @@ extern "C" { Subscripts: &'a DIArray) -> &'a DIType; - pub fn LLVMRustDIBuilderCreateVectorType(Builder: &'a DIBuilder, - Size: u64, - AlignInBits: u32, - Ty: &'a DIType, - Subscripts: &'a DIArray) - -> &'a DIType; - pub fn LLVMRustDIBuilderGetOrCreateSubrange(Builder: &DIBuilder, Lo: i64, Count: i64) @@ -1696,9 +1543,6 @@ extern "C" { pub fn LLVMRustThinLTOAvailable() -> bool; pub fn LLVMRustPGOAvailable() -> bool; - pub fn LLVMRustWriteThinBitcodeToFile(PMR: PassManagerRef, - M: &Module, - BC: *const c_char) -> bool; pub fn LLVMRustThinLTOBufferCreate(M: &Module) -> *mut ThinLTOBuffer; pub fn LLVMRustThinLTOBufferFree(M: *mut ThinLTOBuffer); pub fn LLVMRustThinLTOBufferPtr(M: *const ThinLTOBuffer) -> *const c_char; @@ -1732,7 +1576,6 @@ extern "C" { len: usize, Identifier: *const c_char, ) -> Option<&Module>; - pub fn LLVMGetModuleIdentifier(M: &Module, size: *mut usize) -> *const c_char; pub fn LLVMRustThinLTOGetDICompileUnit(M: &Module, CU1: *mut *mut c_void, CU2: *mut *mut c_void); diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index 85fbc4bf378a5..3f5550bf95fd2 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -828,23 +828,6 @@ LLVMRustPGOAvailable() { // and various online resources about ThinLTO to make heads or tails of all // this. -extern "C" bool -LLVMRustWriteThinBitcodeToFile(LLVMPassManagerRef PMR, - LLVMModuleRef M, - const char *BcFile) { - llvm::legacy::PassManager *PM = unwrap(PMR); - std::error_code EC; - llvm::raw_fd_ostream bc(BcFile, EC, llvm::sys::fs::F_None); - if (EC) { - LLVMRustSetLastError(EC.message().c_str()); - return false; - } - PM->add(createWriteThinLTOBitcodePass(bc)); - PM->run(*unwrap(M)); - delete PM; - return true; -} - // This is a shared data structure which *must* be threadsafe to share // read-only amongst threads. This also corresponds basically to the arguments // of the `ProcessThinLTOModule` function in the LLVM source. @@ -1259,13 +1242,6 @@ LLVMRustThinLTOPatchDICompileUnit(LLVMModuleRef Mod, DICompileUnit *Unit) { #else -extern "C" bool -LLVMRustWriteThinBitcodeToFile(LLVMPassManagerRef PMR, - LLVMModuleRef M, - const char *BcFile) { - report_fatal_error("ThinLTO not available"); -} - struct LLVMRustThinLTOData { }; diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index d82410618d04b..f2b5297285ca7 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -750,15 +750,6 @@ LLVMRustDIBuilderCreateArrayType(LLVMRustDIBuilderRef Builder, uint64_t Size, DINodeArray(unwrapDI(Subscripts)))); } -extern "C" LLVMMetadataRef -LLVMRustDIBuilderCreateVectorType(LLVMRustDIBuilderRef Builder, uint64_t Size, - uint32_t AlignInBits, LLVMMetadataRef Ty, - LLVMMetadataRef Subscripts) { - return wrap( - Builder->createVectorType(Size, AlignInBits, unwrapDI(Ty), - DINodeArray(unwrapDI(Subscripts)))); -} - extern "C" LLVMMetadataRef LLVMRustDIBuilderGetOrCreateSubrange(LLVMRustDIBuilderRef Builder, int64_t Lo, int64_t Count) { From 2f73cef5a3bff0da510bfc35f88bb42009af6035 Mon Sep 17 00:00:00 2001 From: Irina Popa Date: Tue, 10 Jul 2018 19:19:17 +0300 Subject: [PATCH 15/36] rustc_codegen_llvm: use safe references for MemoryBuffer and ObjectFile. --- src/librustc_codegen_llvm/llvm/ffi.rs | 16 +++++++++------- src/librustc_codegen_llvm/llvm/mod.rs | 15 +++++---------- src/librustc_codegen_llvm/metadata.rs | 6 ++---- 3 files changed, 16 insertions(+), 21 deletions(-) diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index d67cc773bbcc8..422eb32bab8f8 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -390,13 +390,11 @@ extern { pub type Metadata; } extern { pub type BasicBlock; } extern { pub type Builder; } extern { pub type MemoryBuffer; } -pub type MemoryBufferRef = *mut MemoryBuffer; extern { pub type PassManager; } pub type PassManagerRef = *mut PassManager; extern { pub type PassManagerBuilder; } pub type PassManagerBuilderRef = *mut PassManagerBuilder; extern { pub type ObjectFile; } -pub type ObjectFileRef = *mut ObjectFile; extern { pub type SectionIterator; } pub type SectionIteratorRef = *mut SectionIterator; extern { pub type Pass; } @@ -1143,17 +1141,19 @@ extern "C" { // Stuff that's in rustllvm/ because it's not upstream yet. /// Opens an object file. - pub fn LLVMCreateObjectFile(MemBuf: MemoryBufferRef) -> ObjectFileRef; + pub fn LLVMCreateObjectFile( + MemBuf: &'static mut MemoryBuffer, + ) -> Option<&'static mut ObjectFile>; /// Closes an object file. - pub fn LLVMDisposeObjectFile(ObjFile: ObjectFileRef); + pub fn LLVMDisposeObjectFile(ObjFile: &'static mut ObjectFile); /// Enumerates the sections in an object file. - pub fn LLVMGetSections(ObjFile: ObjectFileRef) -> SectionIteratorRef; + pub fn LLVMGetSections(ObjFile: &ObjectFile) -> 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; + pub fn LLVMIsSectionIteratorAtEnd(ObjFile: &ObjectFile, SI: SectionIteratorRef) -> Bool; /// Moves the section iterator to point to the next section. pub fn LLVMMoveToNextSection(SI: SectionIteratorRef); /// Returns the current section size. @@ -1163,7 +1163,9 @@ extern "C" { /// 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 LLVMRustCreateMemoryBufferWithContentsOfFile( + Path: *const c_char, + ) -> Option<&'static mut MemoryBuffer>; pub fn LLVMStartMultithreaded() -> Bool; diff --git a/src/librustc_codegen_llvm/llvm/mod.rs b/src/librustc_codegen_llvm/llvm/mod.rs index b4b5ae42d02bd..6bca2a162214c 100644 --- a/src/librustc_codegen_llvm/llvm/mod.rs +++ b/src/librustc_codegen_llvm/llvm/mod.rs @@ -179,21 +179,16 @@ impl Attribute { // Memory-managed interface to object files. pub struct ObjectFile { - pub llof: ObjectFileRef, + pub llof: &'static mut ffi::ObjectFile, } unsafe impl Send for ObjectFile {} impl ObjectFile { // This will take ownership of llmb - pub fn new(llmb: MemoryBufferRef) -> Option { + pub fn new(llmb: &'static mut MemoryBuffer) -> Option { unsafe { - let llof = LLVMCreateObjectFile(llmb); - if llof as isize == 0 { - // LLVMCreateObjectFile took ownership of llmb - return None; - } - + let llof = LLVMCreateObjectFile(llmb)?; Some(ObjectFile { llof: llof }) } } @@ -202,7 +197,7 @@ impl ObjectFile { impl Drop for ObjectFile { fn drop(&mut self) { unsafe { - LLVMDisposeObjectFile(self.llof); + LLVMDisposeObjectFile(&mut *(self.llof as *mut _)); } } } @@ -221,7 +216,7 @@ impl Drop for SectionIter { } } -pub fn mk_section_iter(llof: ObjectFileRef) -> SectionIter { +pub fn mk_section_iter(llof: &ffi::ObjectFile) -> SectionIter { unsafe { SectionIter { llsi: LLVMGetSections(llof) } } } diff --git a/src/librustc_codegen_llvm/metadata.rs b/src/librustc_codegen_llvm/metadata.rs index 144baa65c1bfa..fcb704413ef11 100644 --- a/src/librustc_codegen_llvm/metadata.rs +++ b/src/librustc_codegen_llvm/metadata.rs @@ -58,10 +58,8 @@ impl MetadataLoader for LlvmMetadataLoader { -> Result { unsafe { let buf = common::path2cstr(filename); - let mb = llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf.as_ptr()); - if mb as isize == 0 { - return Err(format!("error reading library: '{}'", filename.display())); - } + let mb = llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf.as_ptr()) + .ok_or_else(|| format!("error reading library: '{}'", filename.display()))?; let of = ObjectFile::new(mb) .map(|of| OwningRef::new(box of)) .ok_or_else(|| format!("provided path not an object file: '{}'", From e9546601a1eb614a50eea2caf41b6fd6905c4d15 Mon Sep 17 00:00:00 2001 From: Irina Popa Date: Thu, 12 Jul 2018 16:24:09 +0300 Subject: [PATCH 16/36] rustc_codegen_llvm: use safe references for PassManagerBuilder. --- src/librustc_codegen_llvm/back/write.rs | 2 +- src/librustc_codegen_llvm/llvm/ffi.rs | 27 ++++++++++++------------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs index ce51a3572d837..c54ce29b4629c 100644 --- a/src/librustc_codegen_llvm/back/write.rs +++ b/src/librustc_codegen_llvm/back/write.rs @@ -2051,7 +2051,7 @@ pub unsafe fn with_llvm_pmb(llmod: &llvm::Module, config: &ModuleConfig, opt_level: llvm::CodeGenOptLevel, prepare_for_thin_lto: bool, - f: &mut dyn FnMut(llvm::PassManagerBuilderRef)) { + f: &mut dyn FnMut(&llvm::PassManagerBuilder)) { use std::ptr; // Create the PassManagerBuilder for LLVM. We configure it with diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index 422eb32bab8f8..8d982303614fa 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -393,7 +393,6 @@ extern { pub type MemoryBuffer; } extern { pub type PassManager; } pub type PassManagerRef = *mut PassManager; extern { pub type PassManagerBuilder; } -pub type PassManagerBuilderRef = *mut PassManagerBuilder; extern { pub type ObjectFile; } extern { pub type SectionIterator; } pub type SectionIteratorRef = *mut SectionIterator; @@ -1119,23 +1118,23 @@ extern "C" { 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, + pub fn LLVMPassManagerBuilderCreate() -> &'static mut PassManagerBuilder; + pub fn LLVMPassManagerBuilderDispose(PMB: &'static mut PassManagerBuilder); + pub fn LLVMPassManagerBuilderSetSizeLevel(PMB: &PassManagerBuilder, Value: Bool); + pub fn LLVMPassManagerBuilderSetDisableUnrollLoops(PMB: &PassManagerBuilder, Value: Bool); + pub fn LLVMPassManagerBuilderUseInlinerWithThreshold(PMB: &PassManagerBuilder, threshold: c_uint); - pub fn LLVMPassManagerBuilderPopulateModulePassManager(PMB: PassManagerBuilderRef, + pub fn LLVMPassManagerBuilderPopulateModulePassManager(PMB: &PassManagerBuilder, PM: PassManagerRef); - pub fn LLVMPassManagerBuilderPopulateFunctionPassManager(PMB: PassManagerBuilderRef, + pub fn LLVMPassManagerBuilderPopulateFunctionPassManager(PMB: &PassManagerBuilder, PM: PassManagerRef); - pub fn LLVMPassManagerBuilderPopulateLTOPassManager(PMB: PassManagerBuilderRef, + pub fn LLVMPassManagerBuilderPopulateLTOPassManager(PMB: &PassManagerBuilder, PM: PassManagerRef, Internalize: Bool, RunInliner: Bool); pub fn LLVMRustPassManagerBuilderPopulateThinLTOPassManager( - PMB: PassManagerBuilderRef, + PMB: &PassManagerBuilder, PM: PassManagerRef) -> bool; // Stuff that's in rustllvm/ because it's not upstream yet. @@ -1439,10 +1438,10 @@ extern "C" { -> Option<&'static mut TargetMachine>; pub fn LLVMRustDisposeTargetMachine(T: &'static mut TargetMachine); pub fn LLVMRustAddAnalysisPasses(T: TargetMachineRef, PM: PassManagerRef, M: &Module); - pub fn LLVMRustAddBuilderLibraryInfo(PMB: PassManagerBuilderRef, - M: &Module, + pub fn LLVMRustAddBuilderLibraryInfo(PMB: &'a PassManagerBuilder, + M: &'a Module, DisableSimplifyLibCalls: bool); - pub fn LLVMRustConfigurePassManagerBuilder(PMB: PassManagerBuilderRef, + pub fn LLVMRustConfigurePassManagerBuilder(PMB: &PassManagerBuilder, OptLevel: CodeGenOptLevel, MergeFunctions: bool, SLPVectorize: bool, @@ -1470,7 +1469,7 @@ extern "C" { pub fn LLVMRustSetLLVMOptions(Argc: c_int, Argv: *const *const c_char); pub fn LLVMRustPrintPasses(); pub fn LLVMRustSetNormalizedTarget(M: &Module, triple: *const c_char); - pub fn LLVMRustAddAlwaysInlinePass(P: PassManagerBuilderRef, AddLifetimes: bool); + pub fn LLVMRustAddAlwaysInlinePass(P: &PassManagerBuilder, AddLifetimes: bool); pub fn LLVMRustRunRestrictionPass(M: &Module, syms: *const *const c_char, len: size_t); pub fn LLVMRustMarkAllFunctionsNounwind(M: &Module); From 55af02019433f20c53c61d490e651ca968264c7e Mon Sep 17 00:00:00 2001 From: Irina Popa Date: Thu, 12 Jul 2018 18:00:49 +0300 Subject: [PATCH 17/36] rustc_codegen_llvm: use safe references for Pass. --- src/librustc_codegen_llvm/back/lto.rs | 6 ++---- src/librustc_codegen_llvm/back/write.rs | 8 ++++---- src/librustc_codegen_llvm/llvm/ffi.rs | 7 +++---- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/librustc_codegen_llvm/back/lto.rs b/src/librustc_codegen_llvm/back/lto.rs index fce34710b8143..c30a436449da4 100644 --- a/src/librustc_codegen_llvm/back/lto.rs +++ b/src/librustc_codegen_llvm/back/lto.rs @@ -468,8 +468,7 @@ fn run_pass_manager(cgcx: &CodegenContext, if config.verify_llvm_ir { let pass = llvm::LLVMRustFindAndCreatePass("verify\0".as_ptr() as *const _); - assert!(!pass.is_null()); - llvm::LLVMRustAddPass(pm, pass); + llvm::LLVMRustAddPass(pm, pass.unwrap()); } // When optimizing for LTO we don't actually pass in `-O0`, but we force @@ -503,8 +502,7 @@ fn run_pass_manager(cgcx: &CodegenContext, if config.verify_llvm_ir { let pass = llvm::LLVMRustFindAndCreatePass("verify\0".as_ptr() as *const _); - assert!(!pass.is_null()); - llvm::LLVMRustAddPass(pm, pass); + llvm::LLVMRustAddPass(pm, pass.unwrap()); } time_ext(cgcx.time_passes, None, "LTO passes", || diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs index c54ce29b4629c..9f99adc34a8c1 100644 --- a/src/librustc_codegen_llvm/back/write.rs +++ b/src/librustc_codegen_llvm/back/write.rs @@ -522,10 +522,10 @@ unsafe fn optimize(cgcx: &CodegenContext, // manager. let addpass = |pass_name: &str| { let pass_name = CString::new(pass_name).unwrap(); - let pass = llvm::LLVMRustFindAndCreatePass(pass_name.as_ptr()); - if pass.is_null() { - return false; - } + let pass = match llvm::LLVMRustFindAndCreatePass(pass_name.as_ptr()) { + Some(pass) => pass, + None => return false, + }; let pass_manager = match llvm::LLVMRustPassKind(pass) { llvm::PassKind::Function => fpm, llvm::PassKind::Module => mpm, diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index 8d982303614fa..ebbb8549b126c 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -397,7 +397,6 @@ extern { pub type ObjectFile; } extern { pub type SectionIterator; } pub type SectionIteratorRef = *mut SectionIterator; extern { pub type Pass; } -pub type PassRef = *mut Pass; extern { pub type TargetMachine; } pub type TargetMachineRef = *const TargetMachine; extern { pub type Archive; } @@ -1414,9 +1413,9 @@ extern "C" { pub fn LLVMIsAConstantInt(value_ref: &Value) -> Option<&Value>; pub fn LLVMIsAConstantFP(value_ref: &Value) -> Option<&Value>; - pub fn LLVMRustPassKind(Pass: PassRef) -> PassKind; - pub fn LLVMRustFindAndCreatePass(Pass: *const c_char) -> PassRef; - pub fn LLVMRustAddPass(PM: PassManagerRef, Pass: PassRef); + pub fn LLVMRustPassKind(Pass: &Pass) -> PassKind; + pub fn LLVMRustFindAndCreatePass(Pass: *const c_char) -> Option<&'static mut Pass>; + pub fn LLVMRustAddPass(PM: PassManagerRef, Pass: &'static mut Pass); pub fn LLVMRustHasFeature(T: TargetMachineRef, s: *const c_char) -> bool; From 0e3a70526952c285a3187b855e2cf3398afe6b38 Mon Sep 17 00:00:00 2001 From: Irina Popa Date: Thu, 12 Jul 2018 18:34:59 +0300 Subject: [PATCH 18/36] rustc_codegen_llvm: use safe references for TargetMachine. --- src/librustc_codegen_llvm/back/lto.rs | 4 ++-- src/librustc_codegen_llvm/back/write.rs | 6 +++--- src/librustc_codegen_llvm/llvm/ffi.rs | 15 +++++++-------- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/librustc_codegen_llvm/back/lto.rs b/src/librustc_codegen_llvm/back/lto.rs index c30a436449da4..0a8b143ae9235 100644 --- a/src/librustc_codegen_llvm/back/lto.rs +++ b/src/librustc_codegen_llvm/back/lto.rs @@ -14,7 +14,7 @@ use back::write::{ModuleConfig, with_llvm_pmb, CodegenContext}; use back::write; use errors::{FatalError, Handler}; use llvm::archive_ro::ArchiveRO; -use llvm::{TargetMachineRef, True, False}; +use llvm::{True, False}; use llvm; use rustc::hir::def_id::LOCAL_CRATE; use rustc::middle::exported_symbols::SymbolExportLevel; @@ -452,7 +452,7 @@ fn thin_lto(diag_handler: &Handler, } fn run_pass_manager(cgcx: &CodegenContext, - tm: TargetMachineRef, + tm: &llvm::TargetMachine, llmod: &llvm::Module, config: &ModuleConfig, thin: bool) { diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs index 9f99adc34a8c1..ebeb0d4bcb463 100644 --- a/src/librustc_codegen_llvm/back/write.rs +++ b/src/librustc_codegen_llvm/back/write.rs @@ -26,7 +26,7 @@ use rustc::session::Session; use rustc::util::nodemap::FxHashMap; use time_graph::{self, TimeGraph, Timeline}; use llvm; -use llvm::{TargetMachineRef, PassManagerRef, DiagnosticInfoRef}; +use llvm::{PassManagerRef, DiagnosticInfoRef}; use llvm::SMDiagnosticRef; use {CodegenResults, ModuleSource, ModuleCodegen, CompiledModule, ModuleKind}; use CrateInfo; @@ -94,7 +94,7 @@ pub fn llvm_err(handler: &errors::Handler, msg: String) -> FatalError { pub fn write_output_file( handler: &errors::Handler, - target: llvm::TargetMachineRef, + target: &llvm::TargetMachine, pm: llvm::PassManagerRef, m: &llvm::Module, output: &Path, @@ -638,7 +638,7 @@ unsafe fn codegen(cgcx: &CodegenContext, // pass manager passed to the closure should be ensured to not // escape the closure itself, and the manager should only be // used once. - unsafe fn with_codegen(tm: TargetMachineRef, + unsafe fn with_codegen(tm: &llvm::TargetMachine, llmod: &llvm::Module, no_builtins: bool, f: F) -> R diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index ebbb8549b126c..566bd3c2c1870 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -398,7 +398,6 @@ extern { pub type SectionIterator; } pub type SectionIteratorRef = *mut SectionIterator; extern { pub type Pass; } extern { pub type TargetMachine; } -pub type TargetMachineRef = *const TargetMachine; extern { pub type Archive; } pub type ArchiveRef = *mut Archive; extern { pub type ArchiveIterator; } @@ -1417,10 +1416,10 @@ extern "C" { pub fn LLVMRustFindAndCreatePass(Pass: *const c_char) -> Option<&'static mut Pass>; pub fn LLVMRustAddPass(PM: PassManagerRef, Pass: &'static mut Pass); - pub fn LLVMRustHasFeature(T: TargetMachineRef, s: *const c_char) -> bool; + pub fn LLVMRustHasFeature(T: &TargetMachine, s: *const c_char) -> bool; - pub fn LLVMRustPrintTargetCPUs(T: TargetMachineRef); - pub fn LLVMRustPrintTargetFeatures(T: TargetMachineRef); + pub fn LLVMRustPrintTargetCPUs(T: &TargetMachine); + pub fn LLVMRustPrintTargetFeatures(T: &TargetMachine); pub fn LLVMRustCreateTargetMachine(Triple: *const c_char, CPU: *const c_char, @@ -1436,7 +1435,7 @@ extern "C" { Singlethread: bool) -> Option<&'static mut TargetMachine>; pub fn LLVMRustDisposeTargetMachine(T: &'static mut TargetMachine); - pub fn LLVMRustAddAnalysisPasses(T: TargetMachineRef, PM: PassManagerRef, M: &Module); + pub fn LLVMRustAddAnalysisPasses(T: &TargetMachine, PM: PassManagerRef, M: &Module); pub fn LLVMRustAddBuilderLibraryInfo(PMB: &'a PassManagerBuilder, M: &'a Module, DisableSimplifyLibCalls: bool); @@ -1452,9 +1451,9 @@ extern "C" { M: &Module, DisableSimplifyLibCalls: bool); pub fn LLVMRustRunFunctionPassManager(PM: PassManagerRef, M: &Module); - pub fn LLVMRustWriteOutputFile(T: TargetMachineRef, + pub fn LLVMRustWriteOutputFile(T: &'a TargetMachine, PM: PassManagerRef, - M: &Module, + M: &'a Module, Output: *const c_char, FileType: FileType) -> LLVMRustResult; @@ -1522,7 +1521,7 @@ extern "C" { -> RustArchiveMemberRef; pub fn LLVMRustArchiveMemberFree(Member: RustArchiveMemberRef); - pub fn LLVMRustSetDataLayoutFromTargetMachine(M: &Module, TM: TargetMachineRef); + pub fn LLVMRustSetDataLayoutFromTargetMachine(M: &'a Module, TM: &'a TargetMachine); pub fn LLVMRustBuildOperandBundleDef(Name: *const c_char, Inputs: *const &Value, From 41d7d8e35e54576d55dc6ed3649a6a6e7d6b749e Mon Sep 17 00:00:00 2001 From: Irina Popa Date: Fri, 13 Jul 2018 13:06:06 +0300 Subject: [PATCH 19/36] rustc_codegen_llvm: use safe references for Archive. --- src/librustc_codegen_llvm/llvm/archive_ro.rs | 21 ++++++++------------ src/librustc_codegen_llvm/llvm/ffi.rs | 7 +++---- 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/src/librustc_codegen_llvm/llvm/archive_ro.rs b/src/librustc_codegen_llvm/llvm/archive_ro.rs index e25f66919614c..98a08f8501af9 100644 --- a/src/librustc_codegen_llvm/llvm/archive_ro.rs +++ b/src/librustc_codegen_llvm/llvm/archive_ro.rs @@ -10,8 +10,6 @@ //! A wrapper around LLVM's archive (.a) code -use super::ArchiveRef; - use std::ffi::CString; use std::marker; use std::path::Path; @@ -19,7 +17,7 @@ use std::slice; use std::str; pub struct ArchiveRO { - ptr: ArchiveRef, + raw: &'static mut super::Archive, } unsafe impl Send for ArchiveRO {} @@ -44,12 +42,9 @@ impl ArchiveRO { pub fn open(dst: &Path) -> Result { 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 }) - } + let ar = super::LLVMRustOpenArchive(s.as_ptr()) + .ok_or_else(|| super::last_error().unwrap_or("failed to open archive".to_string()))?; + Ok(ArchiveRO { raw: ar }) }; #[cfg(unix)] @@ -65,14 +60,14 @@ impl ArchiveRO { } } - pub fn raw(&self) -> ArchiveRef { - self.ptr + pub fn raw(&self) -> &super::Archive { + self.raw } pub fn iter(&self) -> Iter { unsafe { Iter { - ptr: super::LLVMRustArchiveIteratorNew(self.ptr), + ptr: super::LLVMRustArchiveIteratorNew(self.raw), _data: marker::PhantomData, } } @@ -82,7 +77,7 @@ impl ArchiveRO { impl Drop for ArchiveRO { fn drop(&mut self) { unsafe { - super::LLVMRustDestroyArchive(self.ptr); + super::LLVMRustDestroyArchive(&mut *(self.raw as *mut _)); } } } diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index 566bd3c2c1870..f6d206cf5adce 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -399,7 +399,6 @@ pub type SectionIteratorRef = *mut SectionIterator; extern { pub type Pass; } extern { pub type TargetMachine; } extern { pub type Archive; } -pub type ArchiveRef = *mut Archive; extern { pub type ArchiveIterator; } pub type ArchiveIteratorRef = *mut ArchiveIterator; extern { pub type ArchiveChild; } @@ -1471,14 +1470,14 @@ extern "C" { pub fn LLVMRustRunRestrictionPass(M: &Module, syms: *const *const c_char, len: size_t); pub fn LLVMRustMarkAllFunctionsNounwind(M: &Module); - pub fn LLVMRustOpenArchive(path: *const c_char) -> ArchiveRef; - pub fn LLVMRustArchiveIteratorNew(AR: ArchiveRef) -> ArchiveIteratorRef; + pub fn LLVMRustOpenArchive(path: *const c_char) -> Option<&'static mut Archive>; + pub fn LLVMRustArchiveIteratorNew(AR: &Archive) -> 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 LLVMRustDestroyArchive(AR: &'static mut Archive); pub fn LLVMRustGetSectionName(SI: SectionIteratorRef, data: *mut *const c_char) -> size_t; From 44ae6f190993f486d4822dc3da870f564f12b190 Mon Sep 17 00:00:00 2001 From: Irina Popa Date: Fri, 13 Jul 2018 13:59:41 +0300 Subject: [PATCH 20/36] rustc_codegen_llvm: use safe references for Twine, DiagnosticInfo, SMDiagnostic. --- src/librustc_codegen_llvm/back/write.rs | 8 +++---- src/librustc_codegen_llvm/llvm/diagnostic.rs | 18 +++++++------- src/librustc_codegen_llvm/llvm/ffi.rs | 25 +++++++++----------- src/librustc_codegen_llvm/llvm/mod.rs | 2 +- 4 files changed, 24 insertions(+), 29 deletions(-) diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs index ebeb0d4bcb463..7df050e5e9ee4 100644 --- a/src/librustc_codegen_llvm/back/write.rs +++ b/src/librustc_codegen_llvm/back/write.rs @@ -25,9 +25,7 @@ use rustc::session::config::{self, OutputFilenames, OutputType, Passes, SomePass use rustc::session::Session; use rustc::util::nodemap::FxHashMap; use time_graph::{self, TimeGraph, Timeline}; -use llvm; -use llvm::{PassManagerRef, DiagnosticInfoRef}; -use llvm::SMDiagnosticRef; +use llvm::{self, DiagnosticInfo, PassManagerRef, SMDiagnostic}; use {CodegenResults, ModuleSource, ModuleCodegen, CompiledModule, ModuleKind}; use CrateInfo; use rustc::hir::def_id::{CrateNum, LOCAL_CRATE}; @@ -431,7 +429,7 @@ unsafe extern "C" fn report_inline_asm<'a, 'b>(cgcx: &'a CodegenContext, cgcx.diag_emitter.inline_asm_error(cookie as u32, msg.to_string()); } -unsafe extern "C" fn inline_asm_handler(diag: SMDiagnosticRef, +unsafe extern "C" fn inline_asm_handler(diag: &SMDiagnostic, user: *const c_void, cookie: c_uint) { if user.is_null() { @@ -445,7 +443,7 @@ unsafe extern "C" fn inline_asm_handler(diag: SMDiagnosticRef, report_inline_asm(cgcx, &msg, cookie); } -unsafe extern "C" fn diagnostic_handler(info: DiagnosticInfoRef, user: *mut c_void) { +unsafe extern "C" fn diagnostic_handler(info: &DiagnosticInfo, user: *mut c_void) { if user.is_null() { return } diff --git a/src/librustc_codegen_llvm/llvm/diagnostic.rs b/src/librustc_codegen_llvm/llvm/diagnostic.rs index e4c278442d91c..2c28513222679 100644 --- a/src/librustc_codegen_llvm/llvm/diagnostic.rs +++ b/src/librustc_codegen_llvm/llvm/diagnostic.rs @@ -16,7 +16,7 @@ pub use self::Diagnostic::*; use libc::c_uint; use value::Value; -use super::{DiagnosticInfoRef, TwineRef}; +use super::{DiagnosticInfo, Twine}; #[derive(Copy, Clone)] pub enum OptimizationDiagnosticKind { @@ -55,7 +55,7 @@ pub struct OptimizationDiagnostic<'ll> { impl OptimizationDiagnostic<'ll> { unsafe fn unpack( kind: OptimizationDiagnosticKind, - di: DiagnosticInfoRef, + di: &'ll DiagnosticInfo, ) -> Self { let mut function = None; let mut line = 0; @@ -97,14 +97,14 @@ impl OptimizationDiagnostic<'ll> { #[derive(Copy, Clone)] pub struct InlineAsmDiagnostic<'ll> { pub cookie: c_uint, - pub message: TwineRef, + pub message: &'ll Twine, pub instruction: &'ll Value, } impl InlineAsmDiagnostic<'ll> { - unsafe fn unpack(di: DiagnosticInfoRef) -> Self { + unsafe fn unpack(di: &'ll DiagnosticInfo) -> Self { let mut cookie = 0; - let mut message = 0 as *mut _; + let mut message = None; let mut instruction = None; super::LLVMRustUnpackInlineAsmDiagnostic( @@ -116,7 +116,7 @@ impl InlineAsmDiagnostic<'ll> { InlineAsmDiagnostic { cookie, - message, + message: message.unwrap(), instruction: instruction.unwrap(), } } @@ -125,14 +125,14 @@ impl InlineAsmDiagnostic<'ll> { pub enum Diagnostic<'ll> { Optimization(OptimizationDiagnostic<'ll>), InlineAsm(InlineAsmDiagnostic<'ll>), - PGO(DiagnosticInfoRef), + PGO(&'ll DiagnosticInfo), /// LLVM has other types that we do not wrap here. - UnknownDiagnostic(DiagnosticInfoRef), + UnknownDiagnostic(&'ll DiagnosticInfo), } impl Diagnostic<'ll> { - pub unsafe fn unpack(di: DiagnosticInfoRef) -> Self { + pub unsafe fn unpack(di: &'ll DiagnosticInfo) -> Self { use super::DiagnosticKind as Dk; let kind = super::LLVMRustGetDiagInfoKind(di); diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index f6d206cf5adce..a907e9799cd3a 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -404,11 +404,8 @@ pub type ArchiveIteratorRef = *mut ArchiveIterator; extern { pub type ArchiveChild; } pub type ArchiveChildRef = *mut ArchiveChild; extern { pub type Twine; } -pub type TwineRef = *mut Twine; extern { pub type DiagnosticInfo; } -pub type DiagnosticInfoRef = *mut DiagnosticInfo; extern { pub type SMDiagnostic; } -pub type SMDiagnosticRef = *mut SMDiagnostic; extern { pub type RustArchiveMember; } pub type RustArchiveMemberRef = *mut RustArchiveMember; extern { pub type OperandBundleDef; } @@ -416,8 +413,8 @@ pub type OperandBundleDefRef = *mut OperandBundleDef; extern { pub type Linker; } pub type LinkerRef = *mut Linker; -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 type DiagnosticHandler = unsafe extern "C" fn(&DiagnosticInfo, *mut c_void); +pub type InlineAsmDiagHandler = unsafe extern "C" fn(&SMDiagnostic, *const c_void, c_uint); pub mod debuginfo { @@ -1481,32 +1478,32 @@ extern "C" { pub fn LLVMRustGetSectionName(SI: SectionIteratorRef, data: *mut *const c_char) -> size_t; - pub fn LLVMRustWriteTwineToString(T: TwineRef, s: RustStringRef); + pub fn LLVMRustWriteTwineToString(T: &Twine, s: RustStringRef); pub fn LLVMContextSetDiagnosticHandler(C: &Context, Handler: DiagnosticHandler, DiagnosticContext: *mut c_void); - pub fn LLVMRustUnpackOptimizationDiagnostic(DI: DiagnosticInfoRef, + pub fn LLVMRustUnpackOptimizationDiagnostic(DI: &'a DiagnosticInfo, pass_name_out: RustStringRef, - function_out: *mut Option<&Value>, + function_out: *mut Option<&'a Value>, loc_line_out: *mut c_uint, loc_column_out: *mut c_uint, loc_filename_out: RustStringRef, message_out: RustStringRef); - pub fn LLVMRustUnpackInlineAsmDiagnostic(DI: DiagnosticInfoRef, + pub fn LLVMRustUnpackInlineAsmDiagnostic(DI: &'a DiagnosticInfo, cookie_out: *mut c_uint, - message_out: *mut TwineRef, - instruction_out: *mut Option<&Value>); + message_out: *mut Option<&'a Twine>, + instruction_out: *mut Option<&'a Value>); - pub fn LLVMRustWriteDiagnosticInfoToString(DI: DiagnosticInfoRef, s: RustStringRef); - pub fn LLVMRustGetDiagInfoKind(DI: DiagnosticInfoRef) -> DiagnosticKind; + pub fn LLVMRustWriteDiagnosticInfoToString(DI: &DiagnosticInfo, s: RustStringRef); + pub fn LLVMRustGetDiagInfoKind(DI: &DiagnosticInfo) -> DiagnosticKind; pub fn LLVMRustSetInlineAsmDiagnosticHandler(C: &Context, H: InlineAsmDiagHandler, CX: *mut c_void); - pub fn LLVMRustWriteSMDiagnosticToString(d: SMDiagnosticRef, s: RustStringRef); + pub fn LLVMRustWriteSMDiagnosticToString(d: &SMDiagnostic, s: RustStringRef); pub fn LLVMRustWriteArchive(Dst: *const c_char, NumMembers: size_t, diff --git a/src/librustc_codegen_llvm/llvm/mod.rs b/src/librustc_codegen_llvm/llvm/mod.rs index 6bca2a162214c..20c88d94a415d 100644 --- a/src/librustc_codegen_llvm/llvm/mod.rs +++ b/src/librustc_codegen_llvm/llvm/mod.rs @@ -237,7 +237,7 @@ pub fn build_string(f: F) -> Option String::from_utf8(buf.into_inner()).ok() } -pub unsafe fn twine_to_string(tr: TwineRef) -> String { +pub unsafe fn twine_to_string(tr: &Twine) -> String { build_string(|s| LLVMRustWriteTwineToString(tr, s)).expect("got a non-UTF8 Twine from LLVM") } From c1eeb69ce8f922e91b5471e2e84d9289a0cefef1 Mon Sep 17 00:00:00 2001 From: Irina Popa Date: Fri, 13 Jul 2018 14:43:12 +0300 Subject: [PATCH 21/36] rustc_codegen_llvm: use safe references for RustString. --- src/librustc_codegen_llvm/llvm/diagnostic.rs | 6 ++-- src/librustc_codegen_llvm/llvm/ffi.rs | 24 +++++++------- src/librustc_codegen_llvm/llvm/mod.rs | 33 +++++++++++--------- 3 files changed, 33 insertions(+), 30 deletions(-) diff --git a/src/librustc_codegen_llvm/llvm/diagnostic.rs b/src/librustc_codegen_llvm/llvm/diagnostic.rs index 2c28513222679..7f2a9d6984a15 100644 --- a/src/librustc_codegen_llvm/llvm/diagnostic.rs +++ b/src/librustc_codegen_llvm/llvm/diagnostic.rs @@ -73,9 +73,9 @@ impl OptimizationDiagnostic<'ll> { &mut column, filename, message) - ) - ) - ); + ).ok() + ).ok() + ).ok(); let mut filename = filename.unwrap_or(String::new()); if filename.is_empty() { diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index a907e9799cd3a..c2b23246b934b 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -26,7 +26,7 @@ use libc::{c_ulonglong, c_void}; use std::ptr::NonNull; -use super::RustStringRef; +use super::RustString; pub type Bool = c_uint; @@ -1402,8 +1402,8 @@ extern "C" { pub fn LLVMRustDIBuilderCreateOpDeref() -> i64; pub fn LLVMRustDIBuilderCreateOpPlusUconst() -> i64; - pub fn LLVMRustWriteTypeToString(Type: &Type, s: RustStringRef); - pub fn LLVMRustWriteValueToString(value_ref: &Value, s: RustStringRef); + pub fn LLVMRustWriteTypeToString(Type: &Type, s: &RustString); + pub fn LLVMRustWriteValueToString(value_ref: &Value, s: &RustString); pub fn LLVMIsAConstantInt(value_ref: &Value) -> Option<&Value>; pub fn LLVMIsAConstantFP(value_ref: &Value) -> Option<&Value>; @@ -1478,32 +1478,32 @@ extern "C" { pub fn LLVMRustGetSectionName(SI: SectionIteratorRef, data: *mut *const c_char) -> size_t; - pub fn LLVMRustWriteTwineToString(T: &Twine, s: RustStringRef); + pub fn LLVMRustWriteTwineToString(T: &Twine, s: &RustString); pub fn LLVMContextSetDiagnosticHandler(C: &Context, Handler: DiagnosticHandler, DiagnosticContext: *mut c_void); pub fn LLVMRustUnpackOptimizationDiagnostic(DI: &'a DiagnosticInfo, - pass_name_out: RustStringRef, - function_out: *mut Option<&'a Value>, - loc_line_out: *mut c_uint, - loc_column_out: *mut c_uint, - loc_filename_out: RustStringRef, - message_out: RustStringRef); + pass_name_out: &RustString, + function_out: &mut Option<&'a Value>, + loc_line_out: &mut c_uint, + loc_column_out: &mut c_uint, + loc_filename_out: &RustString, + message_out: &RustString); pub fn LLVMRustUnpackInlineAsmDiagnostic(DI: &'a DiagnosticInfo, cookie_out: *mut c_uint, message_out: *mut Option<&'a Twine>, instruction_out: *mut Option<&'a Value>); - pub fn LLVMRustWriteDiagnosticInfoToString(DI: &DiagnosticInfo, s: RustStringRef); + pub fn LLVMRustWriteDiagnosticInfoToString(DI: &DiagnosticInfo, s: &RustString); pub fn LLVMRustGetDiagInfoKind(DI: &DiagnosticInfo) -> DiagnosticKind; pub fn LLVMRustSetInlineAsmDiagnosticHandler(C: &Context, H: InlineAsmDiagHandler, CX: *mut c_void); - pub fn LLVMRustWriteSMDiagnosticToString(d: &SMDiagnostic, s: RustStringRef); + pub fn LLVMRustWriteSMDiagnosticToString(d: &SMDiagnostic, s: &RustString); pub fn LLVMRustWriteArchive(Dst: *const c_char, NumMembers: size_t, diff --git a/src/librustc_codegen_llvm/llvm/mod.rs b/src/librustc_codegen_llvm/llvm/mod.rs index 20c88d94a415d..c27e0d2ae8681 100644 --- a/src/librustc_codegen_llvm/llvm/mod.rs +++ b/src/librustc_codegen_llvm/llvm/mod.rs @@ -22,6 +22,7 @@ pub use self::CallConv::*; pub use self::Linkage::*; use std::str::FromStr; +use std::string::FromUtf8Error; use std::slice; use std::ffi::{CString, CStr}; use std::cell::RefCell; @@ -92,20 +93,19 @@ impl FromStr for ArchiveKind { } } -#[allow(missing_copy_implementations)] -extern { pub type RustString; } -type RustStringRef = *mut RustString; -type RustStringRepr = *mut RefCell>; +#[repr(C)] +pub struct RustString { + bytes: RefCell>, +} /// Appending to a Rust string -- used by RawRustStringOstream. #[no_mangle] -pub unsafe extern "C" fn LLVMRustStringWriteImpl(sr: RustStringRef, +pub unsafe extern "C" fn LLVMRustStringWriteImpl(sr: &RustString, 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); + sr.bytes.borrow_mut().extend_from_slice(slice); } pub fn SetInstructionCallConv(instr: &'a Value, cc: CallConv) { @@ -229,16 +229,19 @@ pub fn get_param(llfn: &'a Value, index: c_uint) -> &'a Value { } } -pub fn build_string(f: F) -> Option - 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 fn build_string(f: impl FnOnce(&RustString)) -> Result { + let sr = RustString { + bytes: RefCell::new(Vec::new()), + }; + f(&sr); + String::from_utf8(sr.bytes.into_inner()) } -pub unsafe fn twine_to_string(tr: &Twine) -> String { - build_string(|s| LLVMRustWriteTwineToString(tr, s)).expect("got a non-UTF8 Twine from LLVM") +pub fn twine_to_string(tr: &Twine) -> String { + unsafe { + build_string(|s| LLVMRustWriteTwineToString(tr, s)) + .expect("got a non-UTF8 Twine from LLVM") + } } pub fn last_error() -> Option { From 92af9694b9d70a78d0fbd0d8d7d421265a244a3c Mon Sep 17 00:00:00 2001 From: Irina Popa Date: Fri, 13 Jul 2018 15:27:55 +0300 Subject: [PATCH 22/36] rustc_codegen_llvm: use safe mutable references for output parameters. --- src/librustc_codegen_llvm/common.rs | 4 ++-- src/librustc_codegen_llvm/llvm/ffi.rs | 20 ++++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/librustc_codegen_llvm/common.rs b/src/librustc_codegen_llvm/common.rs index 90e42dd803aad..fffb3561744f7 100644 --- a/src/librustc_codegen_llvm/common.rs +++ b/src/librustc_codegen_llvm/common.rs @@ -273,7 +273,7 @@ pub fn const_get_real(v: &'ll Value) -> Option<(f64, bool)> { unsafe { if is_const_real(v) { let mut loses_info: llvm::Bool = ::std::mem::uninitialized(); - let r = llvm::LLVMConstRealGetDouble(v, &mut loses_info as *mut llvm::Bool); + let r = llvm::LLVMConstRealGetDouble(v, &mut loses_info); let loses_info = if loses_info == 1 { true } else { false }; Some((r, loses_info)) } else { @@ -311,7 +311,7 @@ pub fn const_to_opt_u128(v: &'ll Value, sign_ext: bool) -> Option { if is_const_integral(v) { let (mut lo, mut hi) = (0u64, 0u64); let success = llvm::LLVMRustConstInt128Get(v, sign_ext, - &mut hi as *mut u64, &mut lo as *mut u64); + &mut hi, &mut lo); if success { Some(hi_lo_to_u128(lo, hi)) } else { diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index c2b23246b934b..d55466726c2fa 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -559,8 +559,8 @@ extern "C" { pub fn LLVMConstIntOfArbitraryPrecision(IntTy: &Type, Wn: c_uint, Ws: *const u64) -> &Value; pub fn LLVMConstIntGetZExtValue(ConstantVal: &Value) -> c_ulonglong; pub fn LLVMRustConstInt128Get(ConstantVal: &Value, SExt: bool, - high: *mut u64, low: *mut u64) -> bool; - pub fn LLVMConstRealGetDouble (ConstantVal: &Value, losesInfo: *mut Bool) -> f64; + high: &mut u64, low: &mut u64) -> bool; + pub fn LLVMConstRealGetDouble (ConstantVal: &Value, losesInfo: &mut Bool) -> f64; // Operations on composite constants @@ -1470,13 +1470,13 @@ extern "C" { pub fn LLVMRustOpenArchive(path: *const c_char) -> Option<&'static mut Archive>; pub fn LLVMRustArchiveIteratorNew(AR: &Archive) -> 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 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: &'static mut Archive); - pub fn LLVMRustGetSectionName(SI: SectionIteratorRef, data: *mut *const c_char) -> size_t; + pub fn LLVMRustGetSectionName(SI: SectionIteratorRef, data: &mut *const c_char) -> size_t; pub fn LLVMRustWriteTwineToString(T: &Twine, s: &RustString); @@ -1492,9 +1492,9 @@ extern "C" { loc_filename_out: &RustString, message_out: &RustString); pub fn LLVMRustUnpackInlineAsmDiagnostic(DI: &'a DiagnosticInfo, - cookie_out: *mut c_uint, - message_out: *mut Option<&'a Twine>, - instruction_out: *mut Option<&'a Value>); + cookie_out: &mut c_uint, + message_out: &mut Option<&'a Twine>, + instruction_out: &mut Option<&'a Value>); pub fn LLVMRustWriteDiagnosticInfoToString(DI: &DiagnosticInfo, s: &RustString); pub fn LLVMRustGetDiagInfoKind(DI: &DiagnosticInfo) -> DiagnosticKind; @@ -1572,8 +1572,8 @@ extern "C" { Identifier: *const c_char, ) -> Option<&Module>; pub fn LLVMRustThinLTOGetDICompileUnit(M: &Module, - CU1: *mut *mut c_void, - CU2: *mut *mut c_void); + CU1: &mut *mut c_void, + CU2: &mut *mut c_void); pub fn LLVMRustThinLTOPatchDICompileUnit(M: &Module, CU: *mut c_void); pub fn LLVMRustLinkerNew(M: &Module) -> LinkerRef; From 0ab344454047966a8cca64d0e55c372534ed866b Mon Sep 17 00:00:00 2001 From: Irina Popa Date: Mon, 16 Jul 2018 16:02:31 +0300 Subject: [PATCH 23/36] rustc_codegen_llvm: use safe references for OperandBundleDef. --- src/librustc_codegen_llvm/builder.rs | 9 ++++----- src/librustc_codegen_llvm/common.rs | 4 ++-- src/librustc_codegen_llvm/llvm/ffi.rs | 20 +++++++++++++------- src/librustc_codegen_llvm/llvm/mod.rs | 18 +++++++----------- 4 files changed, 26 insertions(+), 25 deletions(-) diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index 676523b09f772..2307ad49b5b49 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -23,7 +23,6 @@ use std::borrow::Cow; use std::ffi::CString; use std::ops::Range; use std::ptr; -use std::ptr::NonNull; // All Builders must have an llfn associated with them #[must_use] @@ -176,7 +175,7 @@ impl Builder<'a, 'll, 'tcx> { args: &[&'ll Value], then: &'ll BasicBlock, catch: &'ll BasicBlock, - bundle: Option<&OperandBundleDef>) -> &'ll Value { + bundle: Option<&OperandBundleDef<'ll>>) -> &'ll Value { self.count_insn("invoke"); debug!("Invoke {:?} with args ({:?})", @@ -184,7 +183,7 @@ impl Builder<'a, 'll, 'tcx> { args); let args = self.check_call("invoke", llfn, args); - let bundle = bundle.as_ref().and_then(|b| NonNull::new(b.raw())); + let bundle = bundle.map(|b| &*b.raw); unsafe { llvm::LLVMRustBuildInvoke(self.llbuilder, @@ -724,7 +723,7 @@ impl Builder<'a, 'll, 'tcx> { } pub fn call(&self, llfn: &'ll Value, args: &[&'ll Value], - bundle: Option<&OperandBundleDef>) -> &'ll Value { + bundle: Option<&OperandBundleDef<'ll>>) -> &'ll Value { self.count_insn("call"); debug!("Call {:?} with args ({:?})", @@ -732,7 +731,7 @@ impl Builder<'a, 'll, 'tcx> { args); let args = self.check_call("call", llfn, args); - let bundle = bundle.as_ref().and_then(|b| NonNull::new(b.raw())); + let bundle = bundle.map(|b| &*b.raw); unsafe { llvm::LLVMRustBuildCall(self.llbuilder, llfn, args.as_ptr(), diff --git a/src/librustc_codegen_llvm/common.rs b/src/librustc_codegen_llvm/common.rs index fffb3561744f7..2d0ef7b3eef32 100644 --- a/src/librustc_codegen_llvm/common.rs +++ b/src/librustc_codegen_llvm/common.rs @@ -92,7 +92,7 @@ pub fn type_is_freeze<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> bo /// the `OperandBundleDef` value created for MSVC landing pads. pub struct Funclet<'ll> { cleanuppad: &'ll Value, - operand: OperandBundleDef, + operand: OperandBundleDef<'ll>, } impl Funclet<'ll> { @@ -107,7 +107,7 @@ impl Funclet<'ll> { self.cleanuppad } - pub fn bundle(&self) -> &OperandBundleDef { + pub fn bundle(&self) -> &OperandBundleDef<'ll> { &self.operand } } diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index d55466726c2fa..02a7bc045d6fc 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -24,6 +24,7 @@ use super::debuginfo::{ use libc::{c_uint, c_int, size_t, c_char}; use libc::{c_ulonglong, c_void}; +use std::marker::PhantomData; use std::ptr::NonNull; use super::RustString; @@ -381,6 +382,12 @@ pub enum ThreadLocalMode { LocalExec } +extern { type Opaque; } +struct InvariantOpaque<'a> { + _marker: PhantomData<&'a mut &'a ()>, + _opaque: Opaque, +} + // Opaque pointer types extern { pub type Module; } extern { pub type Context; } @@ -408,8 +415,7 @@ extern { pub type DiagnosticInfo; } extern { pub type SMDiagnostic; } extern { pub type RustArchiveMember; } pub type RustArchiveMemberRef = *mut RustArchiveMember; -extern { pub type OperandBundleDef; } -pub type OperandBundleDefRef = *mut OperandBundleDef; +pub struct OperandBundleDef<'a>(InvariantOpaque<'a>); extern { pub type Linker; } pub type LinkerRef = *mut Linker; @@ -706,7 +712,7 @@ extern "C" { NumArgs: c_uint, Then: &'a BasicBlock, Catch: &'a BasicBlock, - Bundle: Option>, + Bundle: Option<&OperandBundleDef<'a>>, Name: *const c_char) -> &'a Value; pub fn LLVMBuildLandingPad(B: &'a Builder, @@ -975,7 +981,7 @@ extern "C" { Fn: &'a Value, Args: *const &'a Value, NumArgs: c_uint, - Bundle: Option>, + Bundle: Option<&OperandBundleDef<'a>>, Name: *const c_char) -> &'a Value; pub fn LLVMBuildSelect(B: &'a Builder, @@ -1520,10 +1526,10 @@ extern "C" { pub fn LLVMRustSetDataLayoutFromTargetMachine(M: &'a Module, TM: &'a TargetMachine); pub fn LLVMRustBuildOperandBundleDef(Name: *const c_char, - Inputs: *const &Value, + Inputs: *const &'a Value, NumInputs: c_uint) - -> OperandBundleDefRef; - pub fn LLVMRustFreeOperandBundleDef(Bundle: OperandBundleDefRef); + -> &'a mut OperandBundleDef<'a>; + pub fn LLVMRustFreeOperandBundleDef(Bundle: &'a mut OperandBundleDef<'a>); pub fn LLVMRustPositionBuilderAtStart(B: &'a Builder, BB: &'a BasicBlock); diff --git a/src/librustc_codegen_llvm/llvm/mod.rs b/src/librustc_codegen_llvm/llvm/mod.rs index c27e0d2ae8681..93dd98c62dc3e 100644 --- a/src/librustc_codegen_llvm/llvm/mod.rs +++ b/src/librustc_codegen_llvm/llvm/mod.rs @@ -258,28 +258,24 @@ pub fn last_error() -> Option { } } -pub struct OperandBundleDef { - inner: OperandBundleDefRef, +pub struct OperandBundleDef<'a> { + pub raw: &'a mut ffi::OperandBundleDef<'a>, } -impl OperandBundleDef { - pub fn new(name: &str, vals: &[&'a Value]) -> OperandBundleDef { +impl OperandBundleDef<'a> { + pub fn new(name: &str, vals: &[&'a Value]) -> Self { 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 + OperandBundleDef { raw: def } } } -impl Drop for OperandBundleDef { +impl Drop for OperandBundleDef<'a> { fn drop(&mut self) { unsafe { - LLVMRustFreeOperandBundleDef(self.inner); + LLVMRustFreeOperandBundleDef(&mut *(self.raw as *mut _)); } } } From e22eebaf2b1b59c3eed52bd5621c63123af654ad Mon Sep 17 00:00:00 2001 From: Irina Popa Date: Tue, 17 Jul 2018 14:17:47 +0300 Subject: [PATCH 24/36] rustc_codegen_llvm: use safe references for PassManager. --- src/librustc_codegen_llvm/back/write.rs | 94 +++++++++++++------------ src/librustc_codegen_llvm/llvm/ffi.rs | 35 +++++---- 2 files changed, 65 insertions(+), 64 deletions(-) diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs index 7df050e5e9ee4..b3ef98b26cb12 100644 --- a/src/librustc_codegen_llvm/back/write.rs +++ b/src/librustc_codegen_llvm/back/write.rs @@ -25,7 +25,7 @@ use rustc::session::config::{self, OutputFilenames, OutputType, Passes, SomePass use rustc::session::Session; use rustc::util::nodemap::FxHashMap; use time_graph::{self, TimeGraph, Timeline}; -use llvm::{self, DiagnosticInfo, PassManagerRef, SMDiagnostic}; +use llvm::{self, DiagnosticInfo, PassManager, SMDiagnostic}; use {CodegenResults, ModuleSource, ModuleCodegen, CompiledModule, ModuleKind}; use CrateInfo; use rustc::hir::def_id::{CrateNum, LOCAL_CRATE}; @@ -92,9 +92,9 @@ pub fn llvm_err(handler: &errors::Handler, msg: String) -> FatalError { pub fn write_output_file( handler: &errors::Handler, - target: &llvm::TargetMachine, - pm: llvm::PassManagerRef, - m: &llvm::Module, + target: &'ll llvm::TargetMachine, + pm: &llvm::PassManager<'ll>, + m: &'ll llvm::Module, output: &Path, file_type: llvm::FileType) -> Result<(), FatalError> { unsafe { @@ -516,50 +516,52 @@ unsafe fn optimize(cgcx: &CodegenContext, let fpm = llvm::LLVMCreateFunctionPassManagerForModule(llmod); let mpm = llvm::LLVMCreatePassManager(); - // If we're verifying or linting, add them to the function pass - // manager. - let addpass = |pass_name: &str| { - let pass_name = CString::new(pass_name).unwrap(); - let pass = match llvm::LLVMRustFindAndCreatePass(pass_name.as_ptr()) { - Some(pass) => pass, - None => return false, - }; - let pass_manager = match llvm::LLVMRustPassKind(pass) { - llvm::PassKind::Function => fpm, - llvm::PassKind::Module => mpm, - llvm::PassKind::Other => { - diag_handler.err("Encountered LLVM pass kind we can't handle"); - return true - }, + { + // If we're verifying or linting, add them to the function pass + // manager. + let addpass = |pass_name: &str| { + let pass_name = CString::new(pass_name).unwrap(); + let pass = match llvm::LLVMRustFindAndCreatePass(pass_name.as_ptr()) { + Some(pass) => pass, + None => return false, + }; + let pass_manager = match llvm::LLVMRustPassKind(pass) { + llvm::PassKind::Function => &*fpm, + llvm::PassKind::Module => &*mpm, + llvm::PassKind::Other => { + diag_handler.err("Encountered LLVM pass kind we can't handle"); + return true + }, + }; + llvm::LLVMRustAddPass(pass_manager, pass); + true }; - llvm::LLVMRustAddPass(pass_manager, pass); - true - }; - if config.verify_llvm_ir { assert!(addpass("verify")); } - if !config.no_prepopulate_passes { - llvm::LLVMRustAddAnalysisPasses(tm, fpm, llmod); - llvm::LLVMRustAddAnalysisPasses(tm, mpm, llmod); - let opt_level = config.opt_level.unwrap_or(llvm::CodeGenOptLevel::None); - let prepare_for_thin_lto = cgcx.lto == Lto::Thin || cgcx.lto == Lto::ThinLocal; - with_llvm_pmb(llmod, &config, opt_level, prepare_for_thin_lto, &mut |b| { - llvm::LLVMPassManagerBuilderPopulateFunctionPassManager(b, fpm); - llvm::LLVMPassManagerBuilderPopulateModulePassManager(b, mpm); - }) - } + if config.verify_llvm_ir { assert!(addpass("verify")); } + if !config.no_prepopulate_passes { + llvm::LLVMRustAddAnalysisPasses(tm, fpm, llmod); + llvm::LLVMRustAddAnalysisPasses(tm, mpm, llmod); + let opt_level = config.opt_level.unwrap_or(llvm::CodeGenOptLevel::None); + let prepare_for_thin_lto = cgcx.lto == Lto::Thin || cgcx.lto == Lto::ThinLocal; + with_llvm_pmb(llmod, &config, opt_level, prepare_for_thin_lto, &mut |b| { + llvm::LLVMPassManagerBuilderPopulateFunctionPassManager(b, fpm); + llvm::LLVMPassManagerBuilderPopulateModulePassManager(b, mpm); + }) + } - for pass in &config.passes { - if !addpass(pass) { - diag_handler.warn(&format!("unknown pass `{}`, ignoring", - pass)); + for pass in &config.passes { + if !addpass(pass) { + diag_handler.warn(&format!("unknown pass `{}`, ignoring", + pass)); + } } - } - for pass in &cgcx.plugin_passes { - if !addpass(pass) { - diag_handler.err(&format!("a plugin asked for LLVM pass \ - `{}` but LLVM does not \ - recognize it", pass)); + for pass in &cgcx.plugin_passes { + if !addpass(pass) { + diag_handler.err(&format!("a plugin asked for LLVM pass \ + `{}` but LLVM does not \ + recognize it", pass)); + } } } @@ -636,11 +638,11 @@ unsafe fn codegen(cgcx: &CodegenContext, // pass manager passed to the closure should be ensured to not // escape the closure itself, and the manager should only be // used once. - unsafe fn with_codegen(tm: &llvm::TargetMachine, - llmod: &llvm::Module, + unsafe fn with_codegen<'ll, F, R>(tm: &'ll llvm::TargetMachine, + llmod: &'ll llvm::Module, no_builtins: bool, f: F) -> R - where F: FnOnce(PassManagerRef) -> R, + where F: FnOnce(&'ll mut PassManager<'ll>) -> R, { let cpm = llvm::LLVMCreatePassManager(); llvm::LLVMRustAddAnalysisPasses(tm, cpm, llmod); diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index 02a7bc045d6fc..7883315a5dec5 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -397,8 +397,7 @@ extern { pub type Metadata; } extern { pub type BasicBlock; } extern { pub type Builder; } extern { pub type MemoryBuffer; } -extern { pub type PassManager; } -pub type PassManagerRef = *mut PassManager; +pub struct PassManager<'a>(InvariantOpaque<'a>); extern { pub type PassManagerBuilder; } extern { pub type ObjectFile; } extern { pub type SectionIterator; } @@ -1105,16 +1104,16 @@ extern "C" { pub fn LLVMWriteBitcodeToFile(M: &Module, Path: *const c_char) -> c_int; /// Creates a pass manager. - pub fn LLVMCreatePassManager() -> PassManagerRef; + pub fn LLVMCreatePassManager() -> &'a mut PassManager<'a>; /// Creates a function-by-function pass manager - pub fn LLVMCreateFunctionPassManagerForModule(M: &Module) -> PassManagerRef; + pub fn LLVMCreateFunctionPassManagerForModule(M: &'a Module) -> &'a mut PassManager<'a>; /// Disposes a pass manager. - pub fn LLVMDisposePassManager(PM: PassManagerRef); + pub fn LLVMDisposePassManager(PM: &'a mut PassManager<'a>); /// Runs a pass manager on a module. - pub fn LLVMRunPassManager(PM: PassManagerRef, M: &Module) -> Bool; + pub fn LLVMRunPassManager(PM: &PassManager<'a>, M: &'a Module) -> Bool; pub fn LLVMInitializePasses(); @@ -1125,17 +1124,17 @@ extern "C" { pub fn LLVMPassManagerBuilderUseInlinerWithThreshold(PMB: &PassManagerBuilder, threshold: c_uint); pub fn LLVMPassManagerBuilderPopulateModulePassManager(PMB: &PassManagerBuilder, - PM: PassManagerRef); + PM: &PassManager); pub fn LLVMPassManagerBuilderPopulateFunctionPassManager(PMB: &PassManagerBuilder, - PM: PassManagerRef); + PM: &PassManager); pub fn LLVMPassManagerBuilderPopulateLTOPassManager(PMB: &PassManagerBuilder, - PM: PassManagerRef, + PM: &PassManager, Internalize: Bool, RunInliner: Bool); pub fn LLVMRustPassManagerBuilderPopulateThinLTOPassManager( PMB: &PassManagerBuilder, - PM: PassManagerRef) -> bool; + PM: &PassManager) -> bool; // Stuff that's in rustllvm/ because it's not upstream yet. @@ -1416,7 +1415,7 @@ extern "C" { pub fn LLVMRustPassKind(Pass: &Pass) -> PassKind; pub fn LLVMRustFindAndCreatePass(Pass: *const c_char) -> Option<&'static mut Pass>; - pub fn LLVMRustAddPass(PM: PassManagerRef, Pass: &'static mut Pass); + pub fn LLVMRustAddPass(PM: &PassManager, Pass: &'static mut Pass); pub fn LLVMRustHasFeature(T: &TargetMachine, s: *const c_char) -> bool; @@ -1437,7 +1436,7 @@ extern "C" { Singlethread: bool) -> Option<&'static mut TargetMachine>; pub fn LLVMRustDisposeTargetMachine(T: &'static mut TargetMachine); - pub fn LLVMRustAddAnalysisPasses(T: &TargetMachine, PM: PassManagerRef, M: &Module); + pub fn LLVMRustAddAnalysisPasses(T: &'a TargetMachine, PM: &PassManager<'a>, M: &'a Module); pub fn LLVMRustAddBuilderLibraryInfo(PMB: &'a PassManagerBuilder, M: &'a Module, DisableSimplifyLibCalls: bool); @@ -1449,18 +1448,18 @@ extern "C" { PrepareForThinLTO: bool, PGOGenPath: *const c_char, PGOUsePath: *const c_char); - pub fn LLVMRustAddLibraryInfo(PM: PassManagerRef, - M: &Module, + pub fn LLVMRustAddLibraryInfo(PM: &PassManager<'a>, + M: &'a Module, DisableSimplifyLibCalls: bool); - pub fn LLVMRustRunFunctionPassManager(PM: PassManagerRef, M: &Module); + pub fn LLVMRustRunFunctionPassManager(PM: &PassManager<'a>, M: &'a Module); pub fn LLVMRustWriteOutputFile(T: &'a TargetMachine, - PM: PassManagerRef, + PM: &PassManager<'a>, M: &'a Module, Output: *const c_char, FileType: FileType) -> LLVMRustResult; - pub fn LLVMRustPrintModule(PM: PassManagerRef, - M: &Module, + pub fn LLVMRustPrintModule(PM: &PassManager<'a>, + M: &'a Module, Output: *const c_char, Demangle: extern fn(*const c_char, size_t, From 2c1d7fbb8373321d043f4658f310c0b869124cdc Mon Sep 17 00:00:00 2001 From: Irina Popa Date: Tue, 17 Jul 2018 14:22:02 +0300 Subject: [PATCH 25/36] rustc_codegen_llvm: use safe references for SectionIterator. --- src/librustc_codegen_llvm/llvm/ffi.rs | 17 ++++++++--------- src/librustc_codegen_llvm/llvm/mod.rs | 10 +++++----- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index 7883315a5dec5..4b1e8e0626131 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -400,8 +400,7 @@ extern { pub type MemoryBuffer; } pub struct PassManager<'a>(InvariantOpaque<'a>); extern { pub type PassManagerBuilder; } extern { pub type ObjectFile; } -extern { pub type SectionIterator; } -pub type SectionIteratorRef = *mut SectionIterator; +pub struct SectionIterator<'a>(InvariantOpaque<'a>); extern { pub type Pass; } extern { pub type TargetMachine; } extern { pub type Archive; } @@ -1146,18 +1145,18 @@ extern "C" { pub fn LLVMDisposeObjectFile(ObjFile: &'static mut ObjectFile); /// Enumerates the sections in an object file. - pub fn LLVMGetSections(ObjFile: &ObjectFile) -> SectionIteratorRef; + pub fn LLVMGetSections(ObjFile: &'a ObjectFile) -> &'a mut SectionIterator<'a>; /// Destroys a section iterator. - pub fn LLVMDisposeSectionIterator(SI: SectionIteratorRef); + pub fn LLVMDisposeSectionIterator(SI: &'a mut SectionIterator<'a>); /// Returns true if the section iterator is at the end of the section /// list: - pub fn LLVMIsSectionIteratorAtEnd(ObjFile: &ObjectFile, SI: SectionIteratorRef) -> Bool; + pub fn LLVMIsSectionIteratorAtEnd(ObjFile: &'a ObjectFile, SI: &SectionIterator<'a>) -> Bool; /// Moves the section iterator to point to the next section. - pub fn LLVMMoveToNextSection(SI: SectionIteratorRef); + pub fn LLVMMoveToNextSection(SI: &SectionIterator); /// Returns the current section size. - pub fn LLVMGetSectionSize(SI: SectionIteratorRef) -> c_ulonglong; + pub fn LLVMGetSectionSize(SI: &SectionIterator) -> c_ulonglong; /// Returns the current section contents as a string buffer. - pub fn LLVMGetSectionContents(SI: SectionIteratorRef) -> *const c_char; + pub fn LLVMGetSectionContents(SI: &SectionIterator) -> *const c_char; /// Reads the given file and returns it as a memory buffer. Use /// LLVMDisposeMemoryBuffer() to get rid of it. @@ -1481,7 +1480,7 @@ extern "C" { pub fn LLVMRustArchiveIteratorFree(AIR: ArchiveIteratorRef); pub fn LLVMRustDestroyArchive(AR: &'static mut Archive); - pub fn LLVMRustGetSectionName(SI: SectionIteratorRef, data: &mut *const c_char) -> size_t; + pub fn LLVMRustGetSectionName(SI: &SectionIterator, data: &mut *const c_char) -> size_t; pub fn LLVMRustWriteTwineToString(T: &Twine, s: &RustString); diff --git a/src/librustc_codegen_llvm/llvm/mod.rs b/src/librustc_codegen_llvm/llvm/mod.rs index 93dd98c62dc3e..558d2a2bc87b3 100644 --- a/src/librustc_codegen_llvm/llvm/mod.rs +++ b/src/librustc_codegen_llvm/llvm/mod.rs @@ -204,19 +204,19 @@ impl Drop for ObjectFile { // Memory-managed interface to section iterators. -pub struct SectionIter { - pub llsi: SectionIteratorRef, +pub struct SectionIter<'a> { + pub llsi: &'a mut SectionIterator<'a>, } -impl Drop for SectionIter { +impl Drop for SectionIter<'a> { fn drop(&mut self) { unsafe { - LLVMDisposeSectionIterator(self.llsi); + LLVMDisposeSectionIterator(&mut *(self.llsi as *mut _)); } } } -pub fn mk_section_iter(llof: &ffi::ObjectFile) -> SectionIter { +pub fn mk_section_iter(llof: &'a ffi::ObjectFile) -> SectionIter<'a> { unsafe { SectionIter { llsi: LLVMGetSections(llof) } } } From 894467e5b4fd7c355f24c680a612ba810d1b4e8d Mon Sep 17 00:00:00 2001 From: Irina Popa Date: Tue, 17 Jul 2018 14:26:22 +0300 Subject: [PATCH 26/36] rustc_codegen_llvm: use safe references for Linker. --- src/librustc_codegen_llvm/back/lto.rs | 10 +++++----- src/librustc_codegen_llvm/llvm/ffi.rs | 9 ++++----- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/librustc_codegen_llvm/back/lto.rs b/src/librustc_codegen_llvm/back/lto.rs index 0a8b143ae9235..d5d21eb91ecba 100644 --- a/src/librustc_codegen_llvm/back/lto.rs +++ b/src/librustc_codegen_llvm/back/lto.rs @@ -294,10 +294,10 @@ fn fat_lto(cgcx: &CodegenContext, }]) } -struct Linker(llvm::LinkerRef); +struct Linker<'a>(&'a mut llvm::Linker<'a>); -impl Linker { - fn new(llmod: &llvm::Module) -> Linker { +impl Linker<'a> { + fn new(llmod: &'a llvm::Module) -> Self { unsafe { Linker(llvm::LLVMRustLinkerNew(llmod)) } } @@ -314,9 +314,9 @@ impl Linker { } } -impl Drop for Linker { +impl Drop for Linker<'a> { fn drop(&mut self) { - unsafe { llvm::LLVMRustLinkerFree(self.0); } + unsafe { llvm::LLVMRustLinkerFree(&mut *(self.0 as *mut _)); } } } diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index 4b1e8e0626131..ddd7809abc731 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -414,8 +414,7 @@ extern { pub type SMDiagnostic; } extern { pub type RustArchiveMember; } pub type RustArchiveMemberRef = *mut RustArchiveMember; pub struct OperandBundleDef<'a>(InvariantOpaque<'a>); -extern { pub type Linker; } -pub type LinkerRef = *mut Linker; +pub struct Linker<'a>(InvariantOpaque<'a>); pub type DiagnosticHandler = unsafe extern "C" fn(&DiagnosticInfo, *mut c_void); pub type InlineAsmDiagHandler = unsafe extern "C" fn(&SMDiagnostic, *const c_void, c_uint); @@ -1580,9 +1579,9 @@ extern "C" { CU2: &mut *mut c_void); pub fn LLVMRustThinLTOPatchDICompileUnit(M: &Module, CU: *mut c_void); - pub fn LLVMRustLinkerNew(M: &Module) -> LinkerRef; - pub fn LLVMRustLinkerAdd(linker: LinkerRef, + pub fn LLVMRustLinkerNew(M: &'a Module) -> &'a mut Linker<'a>; + pub fn LLVMRustLinkerAdd(linker: &Linker, bytecode: *const c_char, bytecode_len: usize) -> bool; - pub fn LLVMRustLinkerFree(linker: LinkerRef); + pub fn LLVMRustLinkerFree(linker: &'a mut Linker<'a>); } From e551ed90331e236dc8fa6dadeeaa49dcdcb0c2ef Mon Sep 17 00:00:00 2001 From: Irina Popa Date: Tue, 17 Jul 2018 14:31:06 +0300 Subject: [PATCH 27/36] rustc_codegen_llvm: use safe references for ArchiveIterator. --- src/librustc_codegen_llvm/llvm/archive_ro.rs | 6 ++---- src/librustc_codegen_llvm/llvm/ffi.rs | 9 ++++----- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/librustc_codegen_llvm/llvm/archive_ro.rs b/src/librustc_codegen_llvm/llvm/archive_ro.rs index 98a08f8501af9..1d215910d9555 100644 --- a/src/librustc_codegen_llvm/llvm/archive_ro.rs +++ b/src/librustc_codegen_llvm/llvm/archive_ro.rs @@ -23,8 +23,7 @@ pub struct ArchiveRO { unsafe impl Send for ArchiveRO {} pub struct Iter<'a> { - ptr: super::ArchiveIteratorRef, - _data: marker::PhantomData<&'a ArchiveRO>, + ptr: &'a mut super::ArchiveIterator<'a>, } pub struct Child<'a> { @@ -68,7 +67,6 @@ impl ArchiveRO { unsafe { Iter { ptr: super::LLVMRustArchiveIteratorNew(self.raw), - _data: marker::PhantomData, } } } @@ -101,7 +99,7 @@ impl<'a> Iterator for Iter<'a> { impl<'a> Drop for Iter<'a> { fn drop(&mut self) { unsafe { - super::LLVMRustArchiveIteratorFree(self.ptr); + super::LLVMRustArchiveIteratorFree(&mut *(self.ptr as *mut _)); } } } diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index ddd7809abc731..2dda2dd00d2f9 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -404,8 +404,7 @@ pub struct SectionIterator<'a>(InvariantOpaque<'a>); extern { pub type Pass; } extern { pub type TargetMachine; } extern { pub type Archive; } -extern { pub type ArchiveIterator; } -pub type ArchiveIteratorRef = *mut ArchiveIterator; +pub struct ArchiveIterator<'a>(InvariantOpaque<'a>); extern { pub type ArchiveChild; } pub type ArchiveChildRef = *mut ArchiveChild; extern { pub type Twine; } @@ -1471,12 +1470,12 @@ extern "C" { pub fn LLVMRustMarkAllFunctionsNounwind(M: &Module); pub fn LLVMRustOpenArchive(path: *const c_char) -> Option<&'static mut Archive>; - pub fn LLVMRustArchiveIteratorNew(AR: &Archive) -> ArchiveIteratorRef; - pub fn LLVMRustArchiveIteratorNext(AIR: ArchiveIteratorRef) -> ArchiveChildRef; + pub fn LLVMRustArchiveIteratorNew(AR: &'a Archive) -> &'a mut ArchiveIterator<'a>; + pub fn LLVMRustArchiveIteratorNext(AIR: &ArchiveIterator) -> 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 LLVMRustArchiveIteratorFree(AIR: &'a mut ArchiveIterator<'a>); pub fn LLVMRustDestroyArchive(AR: &'static mut Archive); pub fn LLVMRustGetSectionName(SI: &SectionIterator, data: &mut *const c_char) -> size_t; From c7669dff2af371338004cb92cd7d757bc2961d21 Mon Sep 17 00:00:00 2001 From: Irina Popa Date: Tue, 17 Jul 2018 15:02:11 +0300 Subject: [PATCH 28/36] rustc_codegen_llvm: use safe references for ArchiveChild. --- src/librustc_codegen_llvm/back/archive.rs | 6 +-- src/librustc_codegen_llvm/llvm/archive_ro.rs | 39 ++++++---------- src/librustc_codegen_llvm/llvm/ffi.rs | 49 ++++++++++++++++---- 3 files changed, 56 insertions(+), 38 deletions(-) diff --git a/src/librustc_codegen_llvm/back/archive.rs b/src/librustc_codegen_llvm/back/archive.rs index 4ea97911830c7..d290753a5bc29 100644 --- a/src/librustc_codegen_llvm/back/archive.rs +++ b/src/librustc_codegen_llvm/back/archive.rs @@ -14,7 +14,7 @@ use std::ffi::{CString, CStr}; use std::io; use std::mem; use std::path::{Path, PathBuf}; -use std::ptr::{self, NonNull}; +use std::ptr; use std::str; use back::bytecode::RLIB_BYTECODE_EXTENSION; @@ -246,7 +246,7 @@ impl<'a> ArchiveBuilder<'a> { let name = CString::new(child_name)?; members.push(llvm::LLVMRustArchiveMemberNew(ptr::null(), name.as_ptr(), - NonNull::new(child.raw()))); + Some(child.raw))); strings.push(name); } } @@ -284,7 +284,7 @@ impl<'a> ArchiveBuilder<'a> { let name = CString::new(child_name)?; let m = llvm::LLVMRustArchiveMemberNew(ptr::null(), name.as_ptr(), - NonNull::new(child.raw())); + Some(child.raw)); members.push(m); strings.push(name); } diff --git a/src/librustc_codegen_llvm/llvm/archive_ro.rs b/src/librustc_codegen_llvm/llvm/archive_ro.rs index 1d215910d9555..324d52bbef4bc 100644 --- a/src/librustc_codegen_llvm/llvm/archive_ro.rs +++ b/src/librustc_codegen_llvm/llvm/archive_ro.rs @@ -11,24 +11,22 @@ //! A wrapper around LLVM's archive (.a) code use std::ffi::CString; -use std::marker; use std::path::Path; use std::slice; use std::str; pub struct ArchiveRO { - raw: &'static mut super::Archive, + pub raw: &'static mut super::Archive, } unsafe impl Send for ArchiveRO {} pub struct Iter<'a> { - ptr: &'a mut super::ArchiveIterator<'a>, + raw: &'a mut super::ArchiveIterator<'a>, } pub struct Child<'a> { - ptr: super::ArchiveChildRef, - _data: marker::PhantomData<&'a ArchiveRO>, + pub raw: &'a mut super::ArchiveChild<'a>, } impl ArchiveRO { @@ -59,14 +57,10 @@ impl ArchiveRO { } } - pub fn raw(&self) -> &super::Archive { - self.raw - } - pub fn iter(&self) -> Iter { unsafe { Iter { - ptr: super::LLVMRustArchiveIteratorNew(self.raw), + raw: super::LLVMRustArchiveIteratorNew(self.raw), } } } @@ -84,14 +78,11 @@ impl<'a> Iterator for Iter<'a> { type Item = Result, String>; fn next(&mut self) -> Option, 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, - })) + unsafe { + match super::LLVMRustArchiveIteratorNext(self.raw) { + Some(raw) => Some(Ok(Child { raw })), + None => super::last_error().map(Err), + } } } } @@ -99,7 +90,7 @@ impl<'a> Iterator for Iter<'a> { impl<'a> Drop for Iter<'a> { fn drop(&mut self) { unsafe { - super::LLVMRustArchiveIteratorFree(&mut *(self.ptr as *mut _)); + super::LLVMRustArchiveIteratorFree(&mut *(self.raw as *mut _)); } } } @@ -108,7 +99,7 @@ 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); + let name_ptr = super::LLVMRustArchiveChildName(self.raw, &mut name_len); if name_ptr.is_null() { None } else { @@ -121,23 +112,19 @@ impl<'a> Child<'a> { pub fn data(&self) -> &'a [u8] { unsafe { let mut data_len = 0; - let data_ptr = super::LLVMRustArchiveChildData(self.ptr, &mut data_len); + let data_ptr = super::LLVMRustArchiveChildData(self.raw, &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); + super::LLVMRustArchiveChildFree(&mut *(self.raw as *mut _)); } } } diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index 2dda2dd00d2f9..c139868544df7 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -25,7 +25,6 @@ use libc::{c_uint, c_int, size_t, c_char}; use libc::{c_ulonglong, c_void}; use std::marker::PhantomData; -use std::ptr::NonNull; use super::RustString; @@ -383,6 +382,7 @@ pub enum ThreadLocalMode { } extern { type Opaque; } +#[repr(C)] struct InvariantOpaque<'a> { _marker: PhantomData<&'a mut &'a ()>, _opaque: Opaque, @@ -397,22 +397,27 @@ extern { pub type Metadata; } extern { pub type BasicBlock; } extern { pub type Builder; } extern { pub type MemoryBuffer; } +#[repr(C)] pub struct PassManager<'a>(InvariantOpaque<'a>); extern { pub type PassManagerBuilder; } extern { pub type ObjectFile; } +#[repr(C)] pub struct SectionIterator<'a>(InvariantOpaque<'a>); extern { pub type Pass; } extern { pub type TargetMachine; } extern { pub type Archive; } +#[repr(C)] pub struct ArchiveIterator<'a>(InvariantOpaque<'a>); -extern { pub type ArchiveChild; } -pub type ArchiveChildRef = *mut ArchiveChild; +#[repr(C)] +pub struct ArchiveChild<'a>(InvariantOpaque<'a>); extern { pub type Twine; } extern { pub type DiagnosticInfo; } extern { pub type SMDiagnostic; } extern { pub type RustArchiveMember; } pub type RustArchiveMemberRef = *mut RustArchiveMember; +#[repr(C)] pub struct OperandBundleDef<'a>(InvariantOpaque<'a>); +#[repr(C)] pub struct Linker<'a>(InvariantOpaque<'a>); pub type DiagnosticHandler = unsafe extern "C" fn(&DiagnosticInfo, *mut c_void); @@ -474,7 +479,6 @@ pub mod debuginfo { extern { pub type ModuleBuffer; } -#[allow(improper_ctypes)] // TODO remove this (use for NonNull) extern "C" { // Create and destroy contexts. pub fn LLVMRustContextCreate(shouldDiscardNames: bool) -> &'static mut Context; @@ -1403,10 +1407,15 @@ extern "C" { -> &'a Value; pub fn LLVMRustDIBuilderCreateOpDeref() -> i64; pub fn LLVMRustDIBuilderCreateOpPlusUconst() -> i64; +} +#[allow(improper_ctypes)] // FIXME(#52456) needed for RustString. +extern "C" { pub fn LLVMRustWriteTypeToString(Type: &Type, s: &RustString); pub fn LLVMRustWriteValueToString(value_ref: &Value, s: &RustString); +} +extern "C" { pub fn LLVMIsAConstantInt(value_ref: &Value) -> Option<&Value>; pub fn LLVMIsAConstantFP(value_ref: &Value) -> Option<&Value>; @@ -1471,21 +1480,29 @@ extern "C" { pub fn LLVMRustOpenArchive(path: *const c_char) -> Option<&'static mut Archive>; pub fn LLVMRustArchiveIteratorNew(AR: &'a Archive) -> &'a mut ArchiveIterator<'a>; - pub fn LLVMRustArchiveIteratorNext(AIR: &ArchiveIterator) -> 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 LLVMRustArchiveIteratorNext(AIR: &ArchiveIterator<'a>) -> Option<&'a mut ArchiveChild<'a>>; + pub fn LLVMRustArchiveChildName(ACR: &ArchiveChild, size: &mut size_t) -> *const c_char; + pub fn LLVMRustArchiveChildData(ACR: &ArchiveChild, size: &mut size_t) -> *const c_char; + pub fn LLVMRustArchiveChildFree(ACR: &'a mut ArchiveChild<'a>); pub fn LLVMRustArchiveIteratorFree(AIR: &'a mut ArchiveIterator<'a>); pub fn LLVMRustDestroyArchive(AR: &'static mut Archive); pub fn LLVMRustGetSectionName(SI: &SectionIterator, data: &mut *const c_char) -> size_t; +} +#[allow(improper_ctypes)] // FIXME(#52456) needed for RustString. +extern "C" { pub fn LLVMRustWriteTwineToString(T: &Twine, s: &RustString); +} +extern "C" { pub fn LLVMContextSetDiagnosticHandler(C: &Context, Handler: DiagnosticHandler, DiagnosticContext: *mut c_void); +} +#[allow(improper_ctypes)] // FIXME(#52456) needed for RustString. +extern "C" { pub fn LLVMRustUnpackOptimizationDiagnostic(DI: &'a DiagnosticInfo, pass_name_out: &RustString, function_out: &mut Option<&'a Value>, @@ -1493,20 +1510,34 @@ extern "C" { loc_column_out: &mut c_uint, loc_filename_out: &RustString, message_out: &RustString); +} + +extern "C" { pub fn LLVMRustUnpackInlineAsmDiagnostic(DI: &'a DiagnosticInfo, cookie_out: &mut c_uint, message_out: &mut Option<&'a Twine>, instruction_out: &mut Option<&'a Value>); +} +#[allow(improper_ctypes)] // FIXME(#52456) needed for RustString. +extern "C" { pub fn LLVMRustWriteDiagnosticInfoToString(DI: &DiagnosticInfo, s: &RustString); +} + +extern "C" { pub fn LLVMRustGetDiagInfoKind(DI: &DiagnosticInfo) -> DiagnosticKind; pub fn LLVMRustSetInlineAsmDiagnosticHandler(C: &Context, H: InlineAsmDiagHandler, CX: *mut c_void); +} +#[allow(improper_ctypes)] // FIXME(#52456) needed for RustString. +extern "C" { pub fn LLVMRustWriteSMDiagnosticToString(d: &SMDiagnostic, s: &RustString); +} +extern "C" { pub fn LLVMRustWriteArchive(Dst: *const c_char, NumMembers: size_t, Members: *const RustArchiveMemberRef, @@ -1515,7 +1546,7 @@ extern "C" { -> LLVMRustResult; pub fn LLVMRustArchiveMemberNew(Filename: *const c_char, Name: *const c_char, - Child: Option>) + Child: Option<&ArchiveChild>) -> RustArchiveMemberRef; pub fn LLVMRustArchiveMemberFree(Member: RustArchiveMemberRef); From b643e5144e1109bca5e16f85919d66bc53e88325 Mon Sep 17 00:00:00 2001 From: Irina Popa Date: Tue, 17 Jul 2018 16:00:10 +0300 Subject: [PATCH 29/36] rustc_codegen_llvm: use safe references for RustArchiveMember. --- src/librustc_codegen_llvm/back/archive.rs | 20 ++++++++++---------- src/librustc_codegen_llvm/llvm/ffi.rs | 12 ++++++------ 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/librustc_codegen_llvm/back/archive.rs b/src/librustc_codegen_llvm/back/archive.rs index d290753a5bc29..af9efc6d7c417 100644 --- a/src/librustc_codegen_llvm/back/archive.rs +++ b/src/librustc_codegen_llvm/back/archive.rs @@ -226,10 +226,13 @@ impl<'a> ArchiveBuilder<'a> { } fn build_with_llvm(&mut self, kind: ArchiveKind) -> io::Result<()> { - let mut archives = Vec::new(); + let removals = mem::replace(&mut self.removals, Vec::new()); + let mut additions = mem::replace(&mut self.additions, Vec::new()); let mut strings = Vec::new(); let mut members = Vec::new(); - let removals = mem::replace(&mut self.removals, Vec::new()); + + let dst = CString::new(self.config.dst.to_str().unwrap())?; + let should_update_symbols = self.should_update_symbols; unsafe { if let Some(archive) = self.src_archive() { @@ -250,18 +253,18 @@ impl<'a> ArchiveBuilder<'a> { strings.push(name); } } - for addition in mem::replace(&mut self.additions, Vec::new()) { + for addition in &mut additions { match addition { Addition::File { path, name_in_archive } => { let path = CString::new(path.to_str().unwrap())?; - let name = CString::new(name_in_archive)?; + let name = CString::new(name_in_archive.clone())?; members.push(llvm::LLVMRustArchiveMemberNew(path.as_ptr(), name.as_ptr(), None)); strings.push(path); strings.push(name); } - Addition::Archive { archive, mut skip } => { + Addition::Archive { archive, skip } => { for child in archive.iter() { let child = child.map_err(string_to_io_error)?; if !is_relevant_child(&child) { @@ -288,17 +291,14 @@ impl<'a> ArchiveBuilder<'a> { members.push(m); strings.push(name); } - archives.push(archive); } } } - let dst = self.config.dst.to_str().unwrap().as_bytes(); - let dst = CString::new(dst)?; let r = llvm::LLVMRustWriteArchive(dst.as_ptr(), members.len() as libc::size_t, - members.as_ptr(), - self.should_update_symbols, + members.as_ptr() as *const &_, + should_update_symbols, kind); let ret = if r.into_result().is_err() { let err = llvm::LLVMRustGetLastError(); diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index c139868544df7..cbf1c556c6cc3 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -413,8 +413,8 @@ pub struct ArchiveChild<'a>(InvariantOpaque<'a>); extern { pub type Twine; } extern { pub type DiagnosticInfo; } extern { pub type SMDiagnostic; } -extern { pub type RustArchiveMember; } -pub type RustArchiveMemberRef = *mut RustArchiveMember; +#[repr(C)] +pub struct RustArchiveMember<'a>(InvariantOpaque<'a>); #[repr(C)] pub struct OperandBundleDef<'a>(InvariantOpaque<'a>); #[repr(C)] @@ -1540,15 +1540,15 @@ extern "C" { extern "C" { pub fn LLVMRustWriteArchive(Dst: *const c_char, NumMembers: size_t, - Members: *const RustArchiveMemberRef, + Members: *const &RustArchiveMember, WriteSymbtab: bool, Kind: ArchiveKind) -> LLVMRustResult; pub fn LLVMRustArchiveMemberNew(Filename: *const c_char, Name: *const c_char, - Child: Option<&ArchiveChild>) - -> RustArchiveMemberRef; - pub fn LLVMRustArchiveMemberFree(Member: RustArchiveMemberRef); + Child: Option<&'a ArchiveChild>) + -> &'a mut RustArchiveMember<'a>; + pub fn LLVMRustArchiveMemberFree(Member: &'a mut RustArchiveMember<'a>); pub fn LLVMRustSetDataLayoutFromTargetMachine(M: &'a Module, TM: &'a TargetMachine); From ab4f93c7420e34f172b617c0a3dd4d6579d0edb6 Mon Sep 17 00:00:00 2001 From: Irina Popa Date: Tue, 17 Jul 2018 16:08:25 +0300 Subject: [PATCH 30/36] rustc_codegen_llvm: use safe references for ModuleBuffer. --- src/librustc_codegen_llvm/back/lto.rs | 4 ++-- src/librustc_codegen_llvm/llvm/ffi.rs | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/librustc_codegen_llvm/back/lto.rs b/src/librustc_codegen_llvm/back/lto.rs index d5d21eb91ecba..27a8b5c1d0778 100644 --- a/src/librustc_codegen_llvm/back/lto.rs +++ b/src/librustc_codegen_llvm/back/lto.rs @@ -527,7 +527,7 @@ impl SerializedModule { } } -pub struct ModuleBuffer(*mut llvm::ModuleBuffer); +pub struct ModuleBuffer(&'static mut llvm::ModuleBuffer); unsafe impl Send for ModuleBuffer {} unsafe impl Sync for ModuleBuffer {} @@ -550,7 +550,7 @@ impl ModuleBuffer { impl Drop for ModuleBuffer { fn drop(&mut self) { - unsafe { llvm::LLVMRustModuleBufferFree(self.0); } + unsafe { llvm::LLVMRustModuleBufferFree(&mut *(self.0 as *mut _)); } } } diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index cbf1c556c6cc3..6f849e65b2eb9 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -1563,10 +1563,10 @@ extern "C" { pub fn LLVMRustSetComdat(M: &'a Module, V: &'a Value, Name: *const c_char); pub fn LLVMRustUnsetComdat(V: &Value); pub fn LLVMRustSetModulePIELevel(M: &Module); - pub fn LLVMRustModuleBufferCreate(M: &Module) -> *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 LLVMRustModuleBufferCreate(M: &Module) -> &'static mut ModuleBuffer; + pub fn LLVMRustModuleBufferPtr(p: &ModuleBuffer) -> *const u8; + pub fn LLVMRustModuleBufferLen(p: &ModuleBuffer) -> usize; + pub fn LLVMRustModuleBufferFree(p: &'static mut ModuleBuffer); pub fn LLVMRustModuleCost(M: &Module) -> u64; pub fn LLVMRustThinLTOAvailable() -> bool; From 2e3a6af7faf1841d620baee12993f59cccdd4e4c Mon Sep 17 00:00:00 2001 From: Irina Popa Date: Tue, 17 Jul 2018 16:31:09 +0300 Subject: [PATCH 31/36] rustc_codegen_llvm: use safe references for ThinLTOBuffer. --- src/librustc_codegen_llvm/back/lto.rs | 4 ++-- src/librustc_codegen_llvm/llvm/ffi.rs | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/librustc_codegen_llvm/back/lto.rs b/src/librustc_codegen_llvm/back/lto.rs index 27a8b5c1d0778..ce56be734d775 100644 --- a/src/librustc_codegen_llvm/back/lto.rs +++ b/src/librustc_codegen_llvm/back/lto.rs @@ -579,7 +579,7 @@ impl Drop for ThinData { } } -pub struct ThinBuffer(*mut llvm::ThinLTOBuffer); +pub struct ThinBuffer(&'static mut llvm::ThinLTOBuffer); unsafe impl Send for ThinBuffer {} unsafe impl Sync for ThinBuffer {} @@ -604,7 +604,7 @@ impl ThinBuffer { impl Drop for ThinBuffer { fn drop(&mut self) { unsafe { - llvm::LLVMRustThinLTOBufferFree(self.0); + llvm::LLVMRustThinLTOBufferFree(&mut *(self.0 as *mut _)); } } } diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index 6f849e65b2eb9..ce10a98938ec2 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -1571,10 +1571,10 @@ extern "C" { pub fn LLVMRustThinLTOAvailable() -> bool; pub fn LLVMRustPGOAvailable() -> bool; - pub fn LLVMRustThinLTOBufferCreate(M: &Module) -> *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 LLVMRustThinLTOBufferCreate(M: &Module) -> &'static mut ThinLTOBuffer; + pub fn LLVMRustThinLTOBufferFree(M: &'static mut ThinLTOBuffer); + pub fn LLVMRustThinLTOBufferPtr(M: &ThinLTOBuffer) -> *const c_char; + pub fn LLVMRustThinLTOBufferLen(M: &ThinLTOBuffer) -> size_t; pub fn LLVMRustCreateThinLTOData( Modules: *const ThinLTOModule, NumModules: c_uint, From ba006440eeae07cb6d6285a6b64f4374754d2300 Mon Sep 17 00:00:00 2001 From: Irina Popa Date: Tue, 17 Jul 2018 16:43:49 +0300 Subject: [PATCH 32/36] rustc_codegen_llvm: use safe references for ThinLTOData. --- src/librustc_codegen_llvm/back/lto.rs | 13 ++++++------- src/librustc_codegen_llvm/llvm/ffi.rs | 12 ++++++------ 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/librustc_codegen_llvm/back/lto.rs b/src/librustc_codegen_llvm/back/lto.rs index ce56be734d775..daa2fb0528064 100644 --- a/src/librustc_codegen_llvm/back/lto.rs +++ b/src/librustc_codegen_llvm/back/lto.rs @@ -423,11 +423,10 @@ fn thin_lto(diag_handler: &Handler, thin_modules.len() as u32, symbol_white_list.as_ptr(), symbol_white_list.len() as u32, - ); - if data.is_null() { - let msg = "failed to prepare thin LTO context".to_string(); - return Err(write::llvm_err(&diag_handler, msg)) - } + ).ok_or_else(|| { + write::llvm_err(&diag_handler, "failed to prepare thin LTO context".to_string()) + })?; + let data = ThinData(data); info!("thin LTO data created"); timeline.record("data"); @@ -566,7 +565,7 @@ struct ThinShared { module_names: Vec, } -struct ThinData(*mut llvm::ThinLTOData); +struct ThinData(&'static mut llvm::ThinLTOData); unsafe impl Send for ThinData {} unsafe impl Sync for ThinData {} @@ -574,7 +573,7 @@ unsafe impl Sync for ThinData {} impl Drop for ThinData { fn drop(&mut self) { unsafe { - llvm::LLVMRustFreeThinLTOData(self.0); + llvm::LLVMRustFreeThinLTOData(&mut *(self.0 as *mut _)); } } } diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index ce10a98938ec2..ba37eaa4608ba 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -1580,24 +1580,24 @@ extern "C" { NumModules: c_uint, PreservedSymbols: *const *const c_char, PreservedSymbolsLen: c_uint, - ) -> *mut ThinLTOData; + ) -> Option<&'static mut ThinLTOData>; pub fn LLVMRustPrepareThinLTORename( - Data: *const ThinLTOData, + Data: &ThinLTOData, Module: &Module, ) -> bool; pub fn LLVMRustPrepareThinLTOResolveWeak( - Data: *const ThinLTOData, + Data: &ThinLTOData, Module: &Module, ) -> bool; pub fn LLVMRustPrepareThinLTOInternalize( - Data: *const ThinLTOData, + Data: &ThinLTOData, Module: &Module, ) -> bool; pub fn LLVMRustPrepareThinLTOImport( - Data: *const ThinLTOData, + Data: &ThinLTOData, Module: &Module, ) -> bool; - pub fn LLVMRustFreeThinLTOData(Data: *mut ThinLTOData); + pub fn LLVMRustFreeThinLTOData(Data: &'static mut ThinLTOData); pub fn LLVMRustParseBitcodeForThinLTO( Context: &Context, Data: *const u8, From 265f2fa4de8fee5ad2e2c21904e51622de2aec24 Mon Sep 17 00:00:00 2001 From: Irina Popa Date: Tue, 17 Jul 2018 18:26:58 +0300 Subject: [PATCH 33/36] rustc_codegen_llvm: fix tidy errors. --- src/librustc_codegen_llvm/back/write.rs | 5 +++- src/librustc_codegen_llvm/base.rs | 12 ++++++-- src/librustc_codegen_llvm/builder.rs | 30 ++++++++++++------- src/librustc_codegen_llvm/common.rs | 12 ++++++-- src/librustc_codegen_llvm/context.rs | 6 +++- .../debuginfo/create_scope_map.rs | 7 +++-- src/librustc_codegen_llvm/declare.rs | 7 ++++- src/librustc_codegen_llvm/llvm/archive_ro.rs | 5 ++-- src/librustc_codegen_llvm/llvm/ffi.rs | 10 +++++-- src/librustc_codegen_llvm/mir/operand.rs | 7 ++++- 10 files changed, 77 insertions(+), 24 deletions(-) diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs index b3ef98b26cb12..db044878fe745 100644 --- a/src/librustc_codegen_llvm/back/write.rs +++ b/src/librustc_codegen_llvm/back/write.rs @@ -128,7 +128,10 @@ fn get_llvm_opt_size(optimize: config::OptLevel) -> llvm::CodeGenOptSize { } } -pub fn create_target_machine(sess: &Session, find_features: bool) -> &'static mut llvm::TargetMachine { +pub fn create_target_machine( + sess: &Session, + find_features: bool, +) -> &'static mut llvm::TargetMachine { target_machine_factory(sess, find_features)().unwrap_or_else(|err| { llvm_err(sess.diagnostic(), err).raise() }) diff --git a/src/librustc_codegen_llvm/base.rs b/src/librustc_codegen_llvm/base.rs index 40115266e2e2a..8278b443a4c83 100644 --- a/src/librustc_codegen_llvm/base.rs +++ b/src/librustc_codegen_llvm/base.rs @@ -395,14 +395,22 @@ pub fn from_immediate(bx: &Builder<'_, 'll, '_>, val: &'ll Value) -> &'ll Value } } -pub fn to_immediate(bx: &Builder<'_, 'll, '_>, val: &'ll Value, layout: layout::TyLayout) -> &'ll Value { +pub fn to_immediate( + bx: &Builder<'_, 'll, '_>, + val: &'ll Value, + layout: layout::TyLayout, +) -> &'ll Value { if let layout::Abi::Scalar(ref scalar) = layout.abi { return to_immediate_scalar(bx, val, scalar); } val } -pub fn to_immediate_scalar(bx: &Builder<'_, 'll, '_>, val: &'ll Value, scalar: &layout::Scalar) -> &'ll Value { +pub fn to_immediate_scalar( + bx: &Builder<'_, 'll, '_>, + val: &'ll Value, + scalar: &layout::Scalar, +) -> &'ll Value { if scalar.is_bool() { return bx.trunc(val, Type::i1(bx.cx)); } diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index 2307ad49b5b49..2ec5fcae2a648 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -157,14 +157,24 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn cond_br(&self, cond: &'ll Value, then_llbb: &'ll BasicBlock, else_llbb: &'ll BasicBlock) { + pub fn cond_br( + &self, + cond: &'ll Value, + then_llbb: &'ll BasicBlock, + else_llbb: &'ll BasicBlock, + ) { self.count_insn("condbr"); unsafe { llvm::LLVMBuildCondBr(self.llbuilder, cond, then_llbb, else_llbb); } } - pub fn switch(&self, v: &'ll Value, else_llbb: &'ll BasicBlock, num_cases: usize) -> &'ll Value { + pub fn switch( + &self, + v: &'ll Value, + else_llbb: &'ll BasicBlock, + num_cases: usize, + ) -> &'ll Value { unsafe { llvm::LLVMBuildSwitch(self.llbuilder, v, else_llbb, num_cases as c_uint) } @@ -814,8 +824,8 @@ impl Builder<'a, 'll, 'tcx> { // FIXME: add a non-fast math version once // https://bugs.llvm.org/show_bug.cgi?id=36732 // is fixed. - let instr = llvm::LLVMRustBuildVectorReduceFAdd(self.llbuilder, acc, src); - let instr = instr.expect("LLVMRustBuildVectorReduceFAdd is not available in LLVM version < 5.0"); + let instr = llvm::LLVMRustBuildVectorReduceFAdd(self.llbuilder, acc, src) + .expect("LLVMRustBuildVectorReduceFAdd is not available in LLVM version < 5.0"); llvm::LLVMRustSetHasUnsafeAlgebra(instr); instr } @@ -826,8 +836,8 @@ impl Builder<'a, 'll, 'tcx> { // FIXME: add a non-fast math version once // https://bugs.llvm.org/show_bug.cgi?id=36732 // is fixed. - let instr = llvm::LLVMRustBuildVectorReduceFMul(self.llbuilder, acc, src); - let instr = instr.expect("LLVMRustBuildVectorReduceFMul is not available in LLVM version < 5.0"); + let instr = llvm::LLVMRustBuildVectorReduceFMul(self.llbuilder, acc, src) + .expect("LLVMRustBuildVectorReduceFMul is not available in LLVM version < 5.0"); llvm::LLVMRustSetHasUnsafeAlgebra(instr); instr } @@ -884,8 +894,8 @@ impl Builder<'a, 'll, 'tcx> { pub fn vector_reduce_fmin_fast(&self, src: &'ll Value) -> &'ll Value { self.count_insn("vector.reduce.fmin_fast"); unsafe { - let instr = llvm::LLVMRustBuildVectorReduceFMin(self.llbuilder, src, /*NoNaNs:*/ true); - let instr = instr.expect("LLVMRustBuildVectorReduceFMin is not available in LLVM version < 5.0"); + let instr = llvm::LLVMRustBuildVectorReduceFMin(self.llbuilder, src, /*NoNaNs:*/ true) + .expect("LLVMRustBuildVectorReduceFMin is not available in LLVM version < 5.0"); llvm::LLVMRustSetHasUnsafeAlgebra(instr); instr } @@ -893,8 +903,8 @@ impl Builder<'a, 'll, 'tcx> { pub fn vector_reduce_fmax_fast(&self, src: &'ll Value) -> &'ll Value { self.count_insn("vector.reduce.fmax_fast"); unsafe { - let instr = llvm::LLVMRustBuildVectorReduceFMax(self.llbuilder, src, /*NoNaNs:*/ true); - let instr = instr.expect("LLVMRustBuildVectorReduceFMax is not available in LLVM version < 5.0"); + let instr = llvm::LLVMRustBuildVectorReduceFMax(self.llbuilder, src, /*NoNaNs:*/ true) + .expect("LLVMRustBuildVectorReduceFMax is not available in LLVM version < 5.0"); llvm::LLVMRustSetHasUnsafeAlgebra(instr); instr } diff --git a/src/librustc_codegen_llvm/common.rs b/src/librustc_codegen_llvm/common.rs index 2d0ef7b3eef32..51fc610408b52 100644 --- a/src/librustc_codegen_llvm/common.rs +++ b/src/librustc_codegen_llvm/common.rs @@ -183,7 +183,11 @@ pub fn C_u8(cx: &CodegenCx<'ll, '_>, i: u8) -> &'ll Value { // This is a 'c-like' raw string, which differs from // our boxed-and-length-annotated strings. -pub fn C_cstr(cx: &CodegenCx<'ll, '_>, s: LocalInternedString, null_terminated: bool) -> &'ll Value { +pub fn C_cstr( + cx: &CodegenCx<'ll, '_>, + s: LocalInternedString, + null_terminated: bool, +) -> &'ll Value { unsafe { if let Some(&llval) = cx.const_cstr_cache.borrow().get(&s) { return llval; @@ -225,7 +229,11 @@ pub fn C_struct(cx: &CodegenCx<'ll, '_>, elts: &[&'ll Value], packed: bool) -> & C_struct_in_context(cx.llcx, elts, packed) } -pub fn C_struct_in_context(llcx: &'ll llvm::Context, elts: &[&'ll Value], packed: bool) -> &'ll Value { +pub fn C_struct_in_context( + llcx: &'ll llvm::Context, + elts: &[&'ll Value], + packed: bool, +) -> &'ll Value { unsafe { llvm::LLVMConstStructInContext(llcx, elts.as_ptr(), elts.len() as c_uint, diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs index 417af8b2b09ac..11f8e75831eed 100644 --- a/src/librustc_codegen_llvm/context.rs +++ b/src/librustc_codegen_llvm/context.rs @@ -155,7 +155,11 @@ pub fn is_pie_binary(sess: &Session) -> bool { !is_any_library(sess) && get_reloc_model(sess) == llvm::RelocMode::PIC } -pub unsafe fn create_module(sess: &Session, llcx: &'ll llvm::Context, mod_name: &str) -> &'ll llvm::Module { +pub unsafe fn create_module( + sess: &Session, + llcx: &'ll llvm::Context, + mod_name: &str, +) -> &'ll llvm::Module { let mod_name = CString::new(mod_name).unwrap(); let llmod = llvm::LLVMModuleCreateWithNameInContext(mod_name.as_ptr(), llcx); diff --git a/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs b/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs index 4d6744c516cdf..5273032f2d7f5 100644 --- a/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs +++ b/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs @@ -43,8 +43,11 @@ impl MirDebugScope<'ll> { /// Produce DIScope DIEs for each MIR Scope which has variables defined in it. /// If debuginfo is disabled, the returned vector is empty. -pub fn create_mir_scopes(cx: &CodegenCx<'ll, '_>, mir: &Mir, debug_context: &FunctionDebugContext<'ll>) - -> IndexVec> { +pub fn create_mir_scopes( + cx: &CodegenCx<'ll, '_>, + mir: &Mir, + debug_context: &FunctionDebugContext<'ll>, +) -> IndexVec> { let null_scope = MirDebugScope { scope_metadata: None, file_start_pos: BytePos(0), diff --git a/src/librustc_codegen_llvm/declare.rs b/src/librustc_codegen_llvm/declare.rs index c7cd06669fab1..9812d7f9a41a2 100644 --- a/src/librustc_codegen_llvm/declare.rs +++ b/src/librustc_codegen_llvm/declare.rs @@ -55,7 +55,12 @@ pub fn declare_global(cx: &CodegenCx<'ll, '_>, name: &str, ty: &'ll Type) -> &'l /// /// If there’s a value with the same name already declared, the function will /// update the declaration and return existing Value instead. -fn declare_raw_fn(cx: &CodegenCx<'ll, '_>, name: &str, callconv: llvm::CallConv, ty: &'ll Type) -> &'ll Value { +fn declare_raw_fn( + cx: &CodegenCx<'ll, '_>, + name: &str, + callconv: llvm::CallConv, + ty: &'ll Type, +) -> &'ll Value { debug!("declare_raw_fn(name={:?}, ty={:?})", name, ty); let namebuf = CString::new(name).unwrap_or_else(|_|{ bug!("name {:?} contains an interior null byte", name) diff --git a/src/librustc_codegen_llvm/llvm/archive_ro.rs b/src/librustc_codegen_llvm/llvm/archive_ro.rs index 324d52bbef4bc..4cbf0d92d7b99 100644 --- a/src/librustc_codegen_llvm/llvm/archive_ro.rs +++ b/src/librustc_codegen_llvm/llvm/archive_ro.rs @@ -39,8 +39,9 @@ impl ArchiveRO { pub fn open(dst: &Path) -> Result { return unsafe { let s = path2cstr(dst); - let ar = super::LLVMRustOpenArchive(s.as_ptr()) - .ok_or_else(|| super::last_error().unwrap_or("failed to open archive".to_string()))?; + let ar = super::LLVMRustOpenArchive(s.as_ptr()).ok_or_else(|| { + super::last_error().unwrap_or("failed to open archive".to_string()) + })?; Ok(ArchiveRO { raw: ar }) }; diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index ba37eaa4608ba..5febd2ebcaf7b 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -740,7 +740,11 @@ extern "C" { Args: *const &'a Value, Name: *const c_char) -> Option<&'a Value>; - pub fn LLVMRustBuildCatchRet(B: &'a Builder, Pad: &'a Value, BB: &'a BasicBlock) -> Option<&'a Value>; + pub fn LLVMRustBuildCatchRet( + B: &'a Builder, + Pad: &'a Value, + BB: &'a BasicBlock, + ) -> Option<&'a Value>; pub fn LLVMRustBuildCatchSwitch(Builder: &'a Builder, ParentPad: Option<&'a Value>, BB: Option<&'a BasicBlock>, @@ -1480,7 +1484,9 @@ extern "C" { pub fn LLVMRustOpenArchive(path: *const c_char) -> Option<&'static mut Archive>; pub fn LLVMRustArchiveIteratorNew(AR: &'a Archive) -> &'a mut ArchiveIterator<'a>; - pub fn LLVMRustArchiveIteratorNext(AIR: &ArchiveIterator<'a>) -> Option<&'a mut ArchiveChild<'a>>; + pub fn LLVMRustArchiveIteratorNext( + AIR: &ArchiveIterator<'a>, + ) -> Option<&'a mut ArchiveChild<'a>>; pub fn LLVMRustArchiveChildName(ACR: &ArchiveChild, size: &mut size_t) -> *const c_char; pub fn LLVMRustArchiveChildData(ACR: &ArchiveChild, size: &mut size_t) -> *const c_char; pub fn LLVMRustArchiveChildFree(ACR: &'a mut ArchiveChild<'a>); diff --git a/src/librustc_codegen_llvm/mir/operand.rs b/src/librustc_codegen_llvm/mir/operand.rs index f8b18f2f8b8aa..1296f5e4b144e 100644 --- a/src/librustc_codegen_llvm/mir/operand.rs +++ b/src/librustc_codegen_llvm/mir/operand.rs @@ -266,7 +266,12 @@ impl OperandValue<'ll> { self.store_with_flags(bx, dest, MemFlags::NONTEMPORAL); } - fn store_with_flags(self, bx: &Builder<'a, 'll, 'tcx>, dest: PlaceRef<'ll, 'tcx>, flags: MemFlags) { + fn store_with_flags( + self, + bx: &Builder<'a, 'll, 'tcx>, + dest: PlaceRef<'ll, 'tcx>, + flags: MemFlags, + ) { debug!("OperandRef::store: operand={:?}, dest={:?}", self, dest); // Avoid generating stores of zero-sized values, because the only way to have a zero-sized // value is through `undef`, and store itself is useless. From 54c98ab0dd5b777ba093361cdc85ec3933f8c8eb Mon Sep 17 00:00:00 2001 From: Irina Popa Date: Tue, 17 Jul 2018 18:33:09 +0300 Subject: [PATCH 34/36] rustc_codegen_llvm: fix ownership of Builder. --- src/librustc_codegen_llvm/builder.rs | 4 +- src/librustc_codegen_llvm/llvm/ffi.rs | 197 ++++++++++++++------------ 2 files changed, 105 insertions(+), 96 deletions(-) diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index 2ec5fcae2a648..b174cd8c7ac76 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -27,14 +27,14 @@ use std::ptr; // All Builders must have an llfn associated with them #[must_use] pub struct Builder<'a, 'll: 'a, 'tcx: 'll> { - pub llbuilder: &'ll llvm::Builder, + pub llbuilder: &'ll mut llvm::Builder<'ll>, pub cx: &'a CodegenCx<'ll, 'tcx>, } impl Drop for Builder<'a, 'll, 'tcx> { fn drop(&mut self) { unsafe { - llvm::LLVMDisposeBuilder(self.llbuilder); + llvm::LLVMDisposeBuilder(&mut *(self.llbuilder as *mut _)); } } } diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index 5febd2ebcaf7b..902a344e6ebda 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -395,7 +395,8 @@ extern { pub type Type; } extern { pub type Value; } extern { pub type Metadata; } extern { pub type BasicBlock; } -extern { pub type Builder; } +#[repr(C)] +pub struct Builder<'a>(InvariantOpaque<'a>); extern { pub type MemoryBuffer; } #[repr(C)] pub struct PassManager<'a>(InvariantOpaque<'a>); @@ -682,31 +683,31 @@ extern "C" { Count: c_uint); // Instruction builders - pub fn LLVMCreateBuilderInContext(C: &Context) -> &Builder; - pub fn LLVMPositionBuilderAtEnd(Builder: &'a Builder, Block: &'a BasicBlock); - pub fn LLVMGetInsertBlock(Builder: &Builder) -> &BasicBlock; - pub fn LLVMDisposeBuilder(Builder: &Builder); + pub fn LLVMCreateBuilderInContext(C: &'a Context) -> &'a mut Builder<'a>; + pub fn LLVMPositionBuilderAtEnd(Builder: &Builder<'a>, Block: &'a BasicBlock); + pub fn LLVMGetInsertBlock(Builder: &Builder<'a>) -> &'a BasicBlock; + pub fn LLVMDisposeBuilder(Builder: &'a mut Builder<'a>); // Metadata - pub fn LLVMSetCurrentDebugLocation(Builder: &'a Builder, L: Option<&'a Value>); - pub fn LLVMGetCurrentDebugLocation(Builder: &Builder) -> &Value; - pub fn LLVMSetInstDebugLocation(Builder: &'a Builder, Inst: &'a Value); + pub fn LLVMSetCurrentDebugLocation(Builder: &Builder<'a>, L: Option<&'a Value>); + pub fn LLVMGetCurrentDebugLocation(Builder: &Builder<'a>) -> &'a Value; + pub fn LLVMSetInstDebugLocation(Builder: &Builder<'a>, Inst: &'a Value); // Terminators - pub fn LLVMBuildRetVoid(B: &Builder) -> &Value; - pub fn LLVMBuildRet(B: &'a Builder, V: &'a Value) -> &'a Value; - pub fn LLVMBuildBr(B: &'a Builder, Dest: &'a BasicBlock) -> &'a Value; - pub fn LLVMBuildCondBr(B: &'a Builder, + pub fn LLVMBuildRetVoid(B: &Builder<'a>) -> &'a Value; + pub fn LLVMBuildRet(B: &Builder<'a>, V: &'a Value) -> &'a Value; + pub fn LLVMBuildBr(B: &Builder<'a>, Dest: &'a BasicBlock) -> &'a Value; + pub fn LLVMBuildCondBr(B: &Builder<'a>, If: &'a Value, Then: &'a BasicBlock, Else: &'a BasicBlock) -> &'a Value; - pub fn LLVMBuildSwitch(B: &'a Builder, + pub fn LLVMBuildSwitch(B: &Builder<'a>, V: &'a Value, Else: &'a BasicBlock, NumCases: c_uint) -> &'a Value; - pub fn LLVMRustBuildInvoke(B: &'a Builder, + pub fn LLVMRustBuildInvoke(B: &Builder<'a>, Fn: &'a Value, Args: *const &'a Value, NumArgs: c_uint, @@ -715,37 +716,37 @@ extern "C" { Bundle: Option<&OperandBundleDef<'a>>, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildLandingPad(B: &'a Builder, + pub fn LLVMBuildLandingPad(B: &Builder<'a>, Ty: &'a Type, PersFn: &'a Value, NumClauses: c_uint, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildResume(B: &'a Builder, Exn: &'a Value) -> &'a Value; - pub fn LLVMBuildUnreachable(B: &Builder) -> &Value; + pub fn LLVMBuildResume(B: &Builder<'a>, Exn: &'a Value) -> &'a Value; + pub fn LLVMBuildUnreachable(B: &Builder<'a>) -> &'a Value; - pub fn LLVMRustBuildCleanupPad(B: &'a Builder, + pub fn LLVMRustBuildCleanupPad(B: &Builder<'a>, ParentPad: Option<&'a Value>, ArgCnt: c_uint, Args: *const &'a Value, Name: *const c_char) -> Option<&'a Value>; - pub fn LLVMRustBuildCleanupRet(B: &'a Builder, + pub fn LLVMRustBuildCleanupRet(B: &Builder<'a>, CleanupPad: &'a Value, UnwindBB: Option<&'a BasicBlock>) -> Option<&'a Value>; - pub fn LLVMRustBuildCatchPad(B: &'a Builder, + pub fn LLVMRustBuildCatchPad(B: &Builder<'a>, ParentPad: &'a Value, ArgCnt: c_uint, Args: *const &'a Value, Name: *const c_char) -> Option<&'a Value>; pub fn LLVMRustBuildCatchRet( - B: &'a Builder, + B: &Builder<'a>, Pad: &'a Value, BB: &'a BasicBlock, ) -> Option<&'a Value>; - pub fn LLVMRustBuildCatchSwitch(Builder: &'a Builder, + pub fn LLVMRustBuildCatchSwitch(Builder: &Builder<'a>, ParentPad: Option<&'a Value>, BB: Option<&'a BasicBlock>, NumHandlers: c_uint, @@ -764,215 +765,215 @@ extern "C" { pub fn LLVMSetCleanup(LandingPad: &Value, Val: Bool); // Arithmetic - pub fn LLVMBuildAdd(B: &'a Builder, + pub fn LLVMBuildAdd(B: &Builder<'a>, LHS: &'a Value, RHS: &'a Value, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildFAdd(B: &'a Builder, + pub fn LLVMBuildFAdd(B: &Builder<'a>, LHS: &'a Value, RHS: &'a Value, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildSub(B: &'a Builder, + pub fn LLVMBuildSub(B: &Builder<'a>, LHS: &'a Value, RHS: &'a Value, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildFSub(B: &'a Builder, + pub fn LLVMBuildFSub(B: &Builder<'a>, LHS: &'a Value, RHS: &'a Value, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildMul(B: &'a Builder, + pub fn LLVMBuildMul(B: &Builder<'a>, LHS: &'a Value, RHS: &'a Value, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildFMul(B: &'a Builder, + pub fn LLVMBuildFMul(B: &Builder<'a>, LHS: &'a Value, RHS: &'a Value, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildUDiv(B: &'a Builder, + pub fn LLVMBuildUDiv(B: &Builder<'a>, LHS: &'a Value, RHS: &'a Value, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildExactUDiv(B: &'a Builder, + pub fn LLVMBuildExactUDiv(B: &Builder<'a>, LHS: &'a Value, RHS: &'a Value, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildSDiv(B: &'a Builder, + pub fn LLVMBuildSDiv(B: &Builder<'a>, LHS: &'a Value, RHS: &'a Value, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildExactSDiv(B: &'a Builder, + pub fn LLVMBuildExactSDiv(B: &Builder<'a>, LHS: &'a Value, RHS: &'a Value, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildFDiv(B: &'a Builder, + pub fn LLVMBuildFDiv(B: &Builder<'a>, LHS: &'a Value, RHS: &'a Value, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildURem(B: &'a Builder, + pub fn LLVMBuildURem(B: &Builder<'a>, LHS: &'a Value, RHS: &'a Value, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildSRem(B: &'a Builder, + pub fn LLVMBuildSRem(B: &Builder<'a>, LHS: &'a Value, RHS: &'a Value, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildFRem(B: &'a Builder, + pub fn LLVMBuildFRem(B: &Builder<'a>, LHS: &'a Value, RHS: &'a Value, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildShl(B: &'a Builder, + pub fn LLVMBuildShl(B: &Builder<'a>, LHS: &'a Value, RHS: &'a Value, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildLShr(B: &'a Builder, + pub fn LLVMBuildLShr(B: &Builder<'a>, LHS: &'a Value, RHS: &'a Value, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildAShr(B: &'a Builder, + pub fn LLVMBuildAShr(B: &Builder<'a>, LHS: &'a Value, RHS: &'a Value, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildAnd(B: &'a Builder, + pub fn LLVMBuildAnd(B: &Builder<'a>, LHS: &'a Value, RHS: &'a Value, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildOr(B: &'a Builder, + pub fn LLVMBuildOr(B: &Builder<'a>, LHS: &'a Value, RHS: &'a Value, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildXor(B: &'a Builder, + pub fn LLVMBuildXor(B: &Builder<'a>, LHS: &'a Value, RHS: &'a Value, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildNeg(B: &'a Builder, V: &'a Value, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildFNeg(B: &'a Builder, V: &'a Value, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildNot(B: &'a Builder, V: &'a Value, Name: *const c_char) -> &'a Value; + pub fn LLVMBuildNeg(B: &Builder<'a>, V: &'a Value, Name: *const c_char) -> &'a Value; + pub fn LLVMBuildFNeg(B: &Builder<'a>, V: &'a Value, Name: *const c_char) -> &'a Value; + pub fn LLVMBuildNot(B: &Builder<'a>, V: &'a Value, Name: *const c_char) -> &'a Value; pub fn LLVMRustSetHasUnsafeAlgebra(Instr: &Value); // Memory - pub fn LLVMBuildAlloca(B: &'a Builder, Ty: &'a Type, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildLoad(B: &'a Builder, PointerVal: &'a Value, Name: *const c_char) -> &'a Value; + pub fn LLVMBuildAlloca(B: &Builder<'a>, Ty: &'a Type, Name: *const c_char) -> &'a Value; + pub fn LLVMBuildLoad(B: &Builder<'a>, PointerVal: &'a Value, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildStore(B: &'a Builder, Val: &'a Value, Ptr: &'a Value) -> &'a Value; + pub fn LLVMBuildStore(B: &Builder<'a>, Val: &'a Value, Ptr: &'a Value) -> &'a Value; - pub fn LLVMBuildGEP(B: &'a Builder, + pub fn LLVMBuildGEP(B: &Builder<'a>, Pointer: &'a Value, Indices: *const &'a Value, NumIndices: c_uint, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildInBoundsGEP(B: &'a Builder, + pub fn LLVMBuildInBoundsGEP(B: &Builder<'a>, Pointer: &'a Value, Indices: *const &'a Value, NumIndices: c_uint, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildStructGEP(B: &'a Builder, + pub fn LLVMBuildStructGEP(B: &Builder<'a>, Pointer: &'a Value, Idx: c_uint, Name: *const c_char) -> &'a Value; // Casts - pub fn LLVMBuildTrunc(B: &'a Builder, + pub fn LLVMBuildTrunc(B: &Builder<'a>, Val: &'a Value, DestTy: &'a Type, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildZExt(B: &'a Builder, + pub fn LLVMBuildZExt(B: &Builder<'a>, Val: &'a Value, DestTy: &'a Type, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildSExt(B: &'a Builder, + pub fn LLVMBuildSExt(B: &Builder<'a>, Val: &'a Value, DestTy: &'a Type, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildFPToUI(B: &'a Builder, + pub fn LLVMBuildFPToUI(B: &Builder<'a>, Val: &'a Value, DestTy: &'a Type, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildFPToSI(B: &'a Builder, + pub fn LLVMBuildFPToSI(B: &Builder<'a>, Val: &'a Value, DestTy: &'a Type, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildUIToFP(B: &'a Builder, + pub fn LLVMBuildUIToFP(B: &Builder<'a>, Val: &'a Value, DestTy: &'a Type, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildSIToFP(B: &'a Builder, + pub fn LLVMBuildSIToFP(B: &Builder<'a>, Val: &'a Value, DestTy: &'a Type, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildFPTrunc(B: &'a Builder, + pub fn LLVMBuildFPTrunc(B: &Builder<'a>, Val: &'a Value, DestTy: &'a Type, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildFPExt(B: &'a Builder, + pub fn LLVMBuildFPExt(B: &Builder<'a>, Val: &'a Value, DestTy: &'a Type, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildPtrToInt(B: &'a Builder, + pub fn LLVMBuildPtrToInt(B: &Builder<'a>, Val: &'a Value, DestTy: &'a Type, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildIntToPtr(B: &'a Builder, + pub fn LLVMBuildIntToPtr(B: &Builder<'a>, Val: &'a Value, DestTy: &'a Type, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildBitCast(B: &'a Builder, + pub fn LLVMBuildBitCast(B: &Builder<'a>, Val: &'a Value, DestTy: &'a Type, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildPointerCast(B: &'a Builder, + pub fn LLVMBuildPointerCast(B: &Builder<'a>, Val: &'a Value, DestTy: &'a Type, Name: *const c_char) -> &'a Value; - pub fn LLVMRustBuildIntCast(B: &'a Builder, + pub fn LLVMRustBuildIntCast(B: &Builder<'a>, Val: &'a Value, DestTy: &'a Type, IsSized: bool) -> &'a Value; // Comparisons - pub fn LLVMBuildICmp(B: &'a Builder, + pub fn LLVMBuildICmp(B: &Builder<'a>, Op: c_uint, LHS: &'a Value, RHS: &'a Value, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildFCmp(B: &'a Builder, + pub fn LLVMBuildFCmp(B: &Builder<'a>, Op: c_uint, LHS: &'a Value, RHS: &'a Value, @@ -980,111 +981,119 @@ extern "C" { -> &'a Value; // Miscellaneous instructions - pub fn LLVMBuildPhi(B: &'a Builder, Ty: &'a Type, Name: *const c_char) -> &'a Value; - pub fn LLVMRustBuildCall(B: &'a Builder, + pub fn LLVMBuildPhi(B: &Builder<'a>, Ty: &'a Type, Name: *const c_char) -> &'a Value; + pub fn LLVMRustBuildCall(B: &Builder<'a>, Fn: &'a Value, Args: *const &'a Value, NumArgs: c_uint, Bundle: Option<&OperandBundleDef<'a>>, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildSelect(B: &'a Builder, + pub fn LLVMBuildSelect(B: &Builder<'a>, If: &'a Value, Then: &'a Value, Else: &'a Value, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildVAArg(B: &'a Builder, + pub fn LLVMBuildVAArg(B: &Builder<'a>, list: &'a Value, Ty: &'a Type, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildExtractElement(B: &'a Builder, + pub fn LLVMBuildExtractElement(B: &Builder<'a>, VecVal: &'a Value, Index: &'a Value, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildInsertElement(B: &'a Builder, + pub fn LLVMBuildInsertElement(B: &Builder<'a>, VecVal: &'a Value, EltVal: &'a Value, Index: &'a Value, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildShuffleVector(B: &'a Builder, + pub fn LLVMBuildShuffleVector(B: &Builder<'a>, V1: &'a Value, V2: &'a Value, Mask: &'a Value, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildExtractValue(B: &'a Builder, + pub fn LLVMBuildExtractValue(B: &Builder<'a>, AggVal: &'a Value, Index: c_uint, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildInsertValue(B: &'a Builder, + pub fn LLVMBuildInsertValue(B: &Builder<'a>, AggVal: &'a Value, EltVal: &'a Value, Index: c_uint, Name: *const c_char) -> &'a Value; - pub fn LLVMRustBuildVectorReduceFAdd(B: &'a Builder, + pub fn LLVMRustBuildVectorReduceFAdd(B: &Builder<'a>, Acc: &'a Value, Src: &'a Value) -> Option<&'a Value>; - pub fn LLVMRustBuildVectorReduceFMul(B: &'a Builder, + pub fn LLVMRustBuildVectorReduceFMul(B: &Builder<'a>, Acc: &'a Value, Src: &'a Value) -> Option<&'a Value>; - pub fn LLVMRustBuildVectorReduceAdd(B: &'a Builder, + pub fn LLVMRustBuildVectorReduceAdd(B: &Builder<'a>, Src: &'a Value) -> Option<&'a Value>; - pub fn LLVMRustBuildVectorReduceMul(B: &'a Builder, + pub fn LLVMRustBuildVectorReduceMul(B: &Builder<'a>, Src: &'a Value) -> Option<&'a Value>; - pub fn LLVMRustBuildVectorReduceAnd(B: &'a Builder, + pub fn LLVMRustBuildVectorReduceAnd(B: &Builder<'a>, Src: &'a Value) -> Option<&'a Value>; - pub fn LLVMRustBuildVectorReduceOr(B: &'a Builder, + pub fn LLVMRustBuildVectorReduceOr(B: &Builder<'a>, Src: &'a Value) -> Option<&'a Value>; - pub fn LLVMRustBuildVectorReduceXor(B: &'a Builder, + pub fn LLVMRustBuildVectorReduceXor(B: &Builder<'a>, Src: &'a Value) -> Option<&'a Value>; - pub fn LLVMRustBuildVectorReduceMin(B: &'a Builder, + pub fn LLVMRustBuildVectorReduceMin(B: &Builder<'a>, Src: &'a Value, IsSigned: bool) -> Option<&'a Value>; - pub fn LLVMRustBuildVectorReduceMax(B: &'a Builder, + pub fn LLVMRustBuildVectorReduceMax(B: &Builder<'a>, Src: &'a Value, IsSigned: bool) -> Option<&'a Value>; - pub fn LLVMRustBuildVectorReduceFMin(B: &'a Builder, + pub fn LLVMRustBuildVectorReduceFMin(B: &Builder<'a>, Src: &'a Value, IsNaN: bool) -> Option<&'a Value>; - pub fn LLVMRustBuildVectorReduceFMax(B: &'a Builder, + pub fn LLVMRustBuildVectorReduceFMax(B: &Builder<'a>, Src: &'a Value, IsNaN: bool) -> Option<&'a Value>; - pub fn LLVMRustBuildMinNum(B: &'a Builder, LHS: &'a Value, LHS: &'a Value) -> Option<&'a Value>; - pub fn LLVMRustBuildMaxNum(B: &'a Builder, LHS: &'a Value, LHS: &'a Value) -> Option<&'a Value>; + pub fn LLVMRustBuildMinNum( + B: &Builder<'a>, + LHS: &'a Value, + LHS: &'a Value, + ) -> Option<&'a Value>; + pub fn LLVMRustBuildMaxNum( + B: &Builder<'a>, + LHS: &'a Value, + LHS: &'a Value, + ) -> Option<&'a Value>; // Atomic Operations - pub fn LLVMRustBuildAtomicLoad(B: &'a Builder, + pub fn LLVMRustBuildAtomicLoad(B: &Builder<'a>, PointerVal: &'a Value, Name: *const c_char, Order: AtomicOrdering) -> &'a Value; - pub fn LLVMRustBuildAtomicStore(B: &'a Builder, + pub fn LLVMRustBuildAtomicStore(B: &Builder<'a>, Val: &'a Value, Ptr: &'a Value, Order: AtomicOrdering) -> &'a Value; - pub fn LLVMRustBuildAtomicCmpXchg(B: &'a Builder, + pub fn LLVMRustBuildAtomicCmpXchg(B: &Builder<'a>, LHS: &'a Value, CMP: &'a Value, RHS: &'a Value, @@ -1093,7 +1102,7 @@ extern "C" { Weak: Bool) -> &'a Value; - pub fn LLVMBuildAtomicRMW(B: &'a Builder, + pub fn LLVMBuildAtomicRMW(B: &Builder<'a>, Op: AtomicRmwBinOp, LHS: &'a Value, RHS: &'a Value, @@ -1564,7 +1573,7 @@ extern "C" { -> &'a mut OperandBundleDef<'a>; pub fn LLVMRustFreeOperandBundleDef(Bundle: &'a mut OperandBundleDef<'a>); - pub fn LLVMRustPositionBuilderAtStart(B: &'a Builder, BB: &'a BasicBlock); + pub fn LLVMRustPositionBuilderAtStart(B: &Builder<'a>, BB: &'a BasicBlock); pub fn LLVMRustSetComdat(M: &'a Module, V: &'a Value, Name: *const c_char); pub fn LLVMRustUnsetComdat(V: &Value); From 69ed6b928cd427669bf7b8694a86b20a8b672fa7 Mon Sep 17 00:00:00 2001 From: Irina Popa Date: Tue, 17 Jul 2018 18:45:33 +0300 Subject: [PATCH 35/36] rustc_codegen_llvm: fix ownership of DIBuilder. --- src/librustc_codegen_llvm/debuginfo/mod.rs | 11 +++- src/librustc_codegen_llvm/debuginfo/utils.rs | 7 ++- src/librustc_codegen_llvm/llvm/ffi.rs | 61 ++++++++++---------- 3 files changed, 45 insertions(+), 34 deletions(-) diff --git a/src/librustc_codegen_llvm/debuginfo/mod.rs b/src/librustc_codegen_llvm/debuginfo/mod.rs index 3b6b7b2d77b1c..143b122a5a172 100644 --- a/src/librustc_codegen_llvm/debuginfo/mod.rs +++ b/src/librustc_codegen_llvm/debuginfo/mod.rs @@ -69,7 +69,7 @@ const DW_TAG_arg_variable: c_uint = 0x101; pub struct CrateDebugContext<'a, 'tcx> { llcontext: &'a llvm::Context, llmod: &'a llvm::Module, - builder: &'a DIBuilder, + builder: &'a mut DIBuilder<'a>, created_files: RefCell>, created_enum_disr_types: RefCell>, @@ -81,6 +81,14 @@ pub struct CrateDebugContext<'a, 'tcx> { composite_types_completed: RefCell>, } +impl Drop for CrateDebugContext<'a, 'tcx> { + fn drop(&mut self) { + unsafe { + llvm::LLVMRustDIBuilderDispose(&mut *(self.builder as *mut _)); + } + } +} + impl<'a, 'tcx> CrateDebugContext<'a, 'tcx> { pub fn new(llmod: &'a llvm::Module) -> Self { debug!("CrateDebugContext::new"); @@ -166,7 +174,6 @@ pub fn finalize(cx: &CodegenCx) { unsafe { llvm::LLVMRustDIBuilderFinalize(DIB(cx)); - llvm::LLVMRustDIBuilderDispose(DIB(cx)); // Debuginfo generation in LLVM by default uses a higher // version of dwarf than macOS currently understands. We can // instruct LLVM to emit an older version of dwarf, however, diff --git a/src/librustc_codegen_llvm/debuginfo/utils.rs b/src/librustc_codegen_llvm/debuginfo/utils.rs index d4d817abd5600..9f4a555082ad4 100644 --- a/src/librustc_codegen_llvm/debuginfo/utils.rs +++ b/src/librustc_codegen_llvm/debuginfo/utils.rs @@ -36,7 +36,10 @@ pub fn is_node_local_to_unit(cx: &CodegenCx, def_id: DefId) -> bool } #[allow(non_snake_case)] -pub fn create_DIArray(builder: &'ll DIBuilder, arr: &[Option<&'ll DIDescriptor>]) -> &'ll DIArray { +pub fn create_DIArray( + builder: &DIBuilder<'ll>, + arr: &[Option<&'ll DIDescriptor>], +) -> &'ll DIArray { return unsafe { llvm::LLVMRustDIBuilderGetOrCreateArray(builder, arr.as_ptr(), arr.len() as u32) }; @@ -54,7 +57,7 @@ pub fn debug_context(cx: &'a CodegenCx<'ll, 'tcx>) -> &'a CrateDebugContext<'ll, #[inline] #[allow(non_snake_case)] -pub fn DIB(cx: &CodegenCx<'ll, '_>) -> &'ll DIBuilder { +pub fn DIB(cx: &'a CodegenCx<'ll, '_>) -> &'a DIBuilder<'ll> { cx.dbg_cx.as_ref().unwrap().builder } diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index 902a344e6ebda..898d3d6735363 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -426,9 +426,10 @@ pub type InlineAsmDiagHandler = unsafe extern "C" fn(&SMDiagnostic, *const c_voi pub mod debuginfo { - use super::Metadata; + use super::{InvariantOpaque, Metadata}; - extern { pub type DIBuilder; } + #[repr(C)] + pub struct DIBuilder<'a>(InvariantOpaque<'a>); pub type DIDescriptor = Metadata; pub type DIScope = DIDescriptor; @@ -1211,13 +1212,13 @@ extern "C" { pub fn LLVMRustMetadataAsValue(C: &'a Context, MD: &'a Metadata) -> &'a Value; - pub fn LLVMRustDIBuilderCreate(M: &Module) -> &DIBuilder; + pub fn LLVMRustDIBuilderCreate(M: &'a Module) -> &'a mut DIBuilder<'a>; - pub fn LLVMRustDIBuilderDispose(Builder: &DIBuilder); + pub fn LLVMRustDIBuilderDispose(Builder: &'a mut DIBuilder<'a>); pub fn LLVMRustDIBuilderFinalize(Builder: &DIBuilder); - pub fn LLVMRustDIBuilderCreateCompileUnit(Builder: &'a DIBuilder, + pub fn LLVMRustDIBuilderCreateCompileUnit(Builder: &DIBuilder<'a>, Lang: c_uint, File: &'a DIFile, Producer: *const c_char, @@ -1227,17 +1228,17 @@ extern "C" { SplitName: *const c_char) -> &'a DIDescriptor; - pub fn LLVMRustDIBuilderCreateFile(Builder: &DIBuilder, + pub fn LLVMRustDIBuilderCreateFile(Builder: &DIBuilder<'a>, Filename: *const c_char, Directory: *const c_char) - -> &DIFile; + -> &'a DIFile; - pub fn LLVMRustDIBuilderCreateSubroutineType(Builder: &'a DIBuilder, + pub fn LLVMRustDIBuilderCreateSubroutineType(Builder: &DIBuilder<'a>, File: &'a DIFile, ParameterTypes: &'a DIArray) -> &'a DICompositeType; - pub fn LLVMRustDIBuilderCreateFunction(Builder: &'a DIBuilder, + pub fn LLVMRustDIBuilderCreateFunction(Builder: &DIBuilder<'a>, Scope: &'a DIDescriptor, Name: *const c_char, LinkageName: *const c_char, @@ -1254,21 +1255,21 @@ extern "C" { Decl: Option<&'a DIDescriptor>) -> &'a DISubprogram; - pub fn LLVMRustDIBuilderCreateBasicType(Builder: &DIBuilder, + pub fn LLVMRustDIBuilderCreateBasicType(Builder: &DIBuilder<'a>, Name: *const c_char, SizeInBits: u64, AlignInBits: u32, Encoding: c_uint) - -> &DIBasicType; + -> &'a DIBasicType; - pub fn LLVMRustDIBuilderCreatePointerType(Builder: &'a DIBuilder, + pub fn LLVMRustDIBuilderCreatePointerType(Builder: &DIBuilder<'a>, PointeeTy: &'a DIType, SizeInBits: u64, AlignInBits: u32, Name: *const c_char) -> &'a DIDerivedType; - pub fn LLVMRustDIBuilderCreateStructType(Builder: &'a DIBuilder, + pub fn LLVMRustDIBuilderCreateStructType(Builder: &DIBuilder<'a>, Scope: Option<&'a DIDescriptor>, Name: *const c_char, File: &'a DIFile, @@ -1283,7 +1284,7 @@ extern "C" { UniqueId: *const c_char) -> &'a DICompositeType; - pub fn LLVMRustDIBuilderCreateMemberType(Builder: &'a DIBuilder, + pub fn LLVMRustDIBuilderCreateMemberType(Builder: &DIBuilder<'a>, Scope: &'a DIDescriptor, Name: *const c_char, File: &'a DIFile, @@ -1295,19 +1296,19 @@ extern "C" { Ty: &'a DIType) -> &'a DIDerivedType; - pub fn LLVMRustDIBuilderCreateLexicalBlock(Builder: &'a DIBuilder, + pub fn LLVMRustDIBuilderCreateLexicalBlock(Builder: &DIBuilder<'a>, Scope: &'a DIScope, File: &'a DIFile, Line: c_uint, Col: c_uint) -> &'a DILexicalBlock; - pub fn LLVMRustDIBuilderCreateLexicalBlockFile(Builder: &'a DIBuilder, + pub fn LLVMRustDIBuilderCreateLexicalBlockFile(Builder: &DIBuilder<'a>, Scope: &'a DIScope, File: &'a DIFile) -> &'a DILexicalBlock; - pub fn LLVMRustDIBuilderCreateStaticVariable(Builder: &'a DIBuilder, + pub fn LLVMRustDIBuilderCreateStaticVariable(Builder: &DIBuilder<'a>, Context: Option<&'a DIScope>, Name: *const c_char, LinkageName: *const c_char, @@ -1320,7 +1321,7 @@ extern "C" { AlignInBits: u32) -> &'a DIGlobalVariable; - pub fn LLVMRustDIBuilderCreateVariable(Builder: &'a DIBuilder, + pub fn LLVMRustDIBuilderCreateVariable(Builder: &DIBuilder<'a>, Tag: c_uint, Scope: &'a DIDescriptor, Name: *const c_char, @@ -1333,24 +1334,24 @@ extern "C" { AlignInBits: u32) -> &'a DIVariable; - pub fn LLVMRustDIBuilderCreateArrayType(Builder: &'a DIBuilder, + pub fn LLVMRustDIBuilderCreateArrayType(Builder: &DIBuilder<'a>, Size: u64, AlignInBits: u32, Ty: &'a DIType, Subscripts: &'a DIArray) -> &'a DIType; - pub fn LLVMRustDIBuilderGetOrCreateSubrange(Builder: &DIBuilder, + pub fn LLVMRustDIBuilderGetOrCreateSubrange(Builder: &DIBuilder<'a>, Lo: i64, Count: i64) - -> &DISubrange; + -> &'a DISubrange; - pub fn LLVMRustDIBuilderGetOrCreateArray(Builder: &'a DIBuilder, + pub fn LLVMRustDIBuilderGetOrCreateArray(Builder: &DIBuilder<'a>, Ptr: *const Option<&'a DIDescriptor>, Count: c_uint) -> &'a DIArray; - pub fn LLVMRustDIBuilderInsertDeclareAtEnd(Builder: &'a DIBuilder, + pub fn LLVMRustDIBuilderInsertDeclareAtEnd(Builder: &DIBuilder<'a>, Val: &'a Value, VarInfo: &'a DIVariable, AddrOps: *const i64, @@ -1359,12 +1360,12 @@ extern "C" { InsertAtEnd: &'a BasicBlock) -> &'a Value; - pub fn LLVMRustDIBuilderCreateEnumerator(Builder: &DIBuilder, + pub fn LLVMRustDIBuilderCreateEnumerator(Builder: &DIBuilder<'a>, Name: *const c_char, Val: u64) - -> &DIEnumerator; + -> &'a DIEnumerator; - pub fn LLVMRustDIBuilderCreateEnumerationType(Builder: &'a DIBuilder, + pub fn LLVMRustDIBuilderCreateEnumerationType(Builder: &DIBuilder<'a>, Scope: &'a DIScope, Name: *const c_char, File: &'a DIFile, @@ -1375,7 +1376,7 @@ extern "C" { ClassType: &'a DIType) -> &'a DIType; - pub fn LLVMRustDIBuilderCreateUnionType(Builder: &'a DIBuilder, + pub fn LLVMRustDIBuilderCreateUnionType(Builder: &DIBuilder<'a>, Scope: &'a DIScope, Name: *const c_char, File: &'a DIFile, @@ -1390,7 +1391,7 @@ extern "C" { pub fn LLVMSetUnnamedAddr(GlobalVar: &Value, UnnamedAddr: Bool); - pub fn LLVMRustDIBuilderCreateTemplateTypeParameter(Builder: &'a DIBuilder, + pub fn LLVMRustDIBuilderCreateTemplateTypeParameter(Builder: &DIBuilder<'a>, Scope: Option<&'a DIScope>, Name: *const c_char, Ty: &'a DIType, @@ -1400,14 +1401,14 @@ extern "C" { -> &'a DITemplateTypeParameter; - pub fn LLVMRustDIBuilderCreateNameSpace(Builder: &'a DIBuilder, + pub fn LLVMRustDIBuilderCreateNameSpace(Builder: &DIBuilder<'a>, Scope: Option<&'a DIScope>, Name: *const c_char, File: &'a DIFile, LineNo: c_uint) -> &'a DINameSpace; - pub fn LLVMRustDICompositeTypeSetTypeArray(Builder: &'a DIBuilder, + pub fn LLVMRustDICompositeTypeSetTypeArray(Builder: &DIBuilder<'a>, CompositeType: &'a DIType, TypeArray: &'a DIArray); From baff67d51f691734ecee0faa83acee91ec16cc5d Mon Sep 17 00:00:00 2001 From: Irina Popa Date: Tue, 31 Jul 2018 15:36:38 +0300 Subject: [PATCH 36/36] rustc_llvm: fix linking on mingw. --- src/librustc_llvm/build.rs | 1 + src/librustc_llvm/lib.rs | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/librustc_llvm/build.rs b/src/librustc_llvm/build.rs index 1619637b827df..5910e55def396 100644 --- a/src/librustc_llvm/build.rs +++ b/src/librustc_llvm/build.rs @@ -271,5 +271,6 @@ fn main() { if target.contains("windows-gnu") { println!("cargo:rustc-link-lib=static-nobundle=gcc_s"); println!("cargo:rustc-link-lib=static-nobundle=pthread"); + println!("cargo:rustc-link-lib=dylib=uuid"); } } diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs index 76ec5b5352309..05f6b5b5fbd28 100644 --- a/src/librustc_llvm/lib.rs +++ b/src/librustc_llvm/lib.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(static_nobundle)] + #![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/")]