]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_codegen_llvm/back/write.rs
Removed code duplication for CommonWriteMethods
[rust.git] / src / librustc_codegen_llvm / back / write.rs
index b55121ca69048b706fb921a221706b77e64949ca..24f58ac59c15ca244880c284de920531d9c9e178 100644 (file)
@@ -24,7 +24,7 @@
 use rustc::session::Session;
 use rustc::util::nodemap::FxHashMap;
 use time_graph::{self, TimeGraph, Timeline};
-use llvm::{self, DiagnosticInfo, PassManager, SMDiagnostic};
+use llvm::{self, DiagnosticInfo, PassManager, SMDiagnostic, BasicBlock};
 use llvm_util;
 use {CodegenResults, ModuleCodegen, CompiledModule, ModuleKind, // ModuleLlvm,
      CachedModuleCodegen};
 use syntax_pos::symbol::Symbol;
 use type_::Type;
 use context::{is_pie_binary, get_reloc_model};
-use common::{C_bytes_in_context, val_ty};
+use interfaces::{Backend, CommonWriteMethods};
+use common;
 use jobserver::{Client, Acquired};
 use rustc_demangle;
+use value::Value;
+use std::marker::PhantomData;
 
 use std::any::Any;
 use std::ffi::{CString, CStr};
@@ -64,7 +67,7 @@
 use std::thread;
 use libc::{c_uint, c_void, c_char, size_t};
 
-pub const RELOC_MODEL_ARGS : [(&'static str, llvm::RelocMode); 7] = [
+pub const RELOC_MODEL_ARGS : [(&str, llvm::RelocMode); 7] = [
     ("pic", llvm::RelocMode::PIC),
     ("static", llvm::RelocMode::Static),
     ("default", llvm::RelocMode::Default),
@@ -81,7 +84,7 @@
     ("large", llvm::CodeModel::Large),
 ];
 
-pub const TLS_MODEL_ARGS : [(&'static str, llvm::ThreadLocalMode); 4] = [
+pub const TLS_MODEL_ARGS : [(&str, llvm::ThreadLocalMode); 4] = [
     ("global-dynamic", llvm::ThreadLocalMode::GeneralDynamic),
     ("local-dynamic", llvm::ThreadLocalMode::LocalDynamic),
     ("initial-exec", llvm::ThreadLocalMode::InitialExec),
@@ -90,7 +93,7 @@
 
 const PRE_THIN_LTO_BC_EXT: &str = "pre-thin-lto.bc";
 
-pub fn llvm_err(handler: &errors::Handler, msg: String) -> FatalError {
+pub fn llvm_err(handler: &errors::Handler, msg: &str) -> FatalError {
     match llvm::last_error() {
         Some(err) => handler.fatal(&format!("{}: {}", msg, err)),
         None => handler.fatal(&msg),
@@ -109,7 +112,7 @@ pub fn write_output_file(
         let result = llvm::LLVMRustWriteOutputFile(target, pm, m, output_c.as_ptr(), file_type);
         if result.into_result().is_err() {
             let msg = format!("could not write output to {}", output.display());
-            Err(llvm_err(handler, msg))
+            Err(llvm_err(handler, &msg))
         } else {
             Ok(())
         }
@@ -139,7 +142,7 @@ pub fn create_target_machine(
     find_features: bool,
 ) -> &'static mut llvm::TargetMachine {
     target_machine_factory(sess, find_features)().unwrap_or_else(|err| {
-        llvm_err(sess.diagnostic(), err).raise()
+        llvm_err(sess.diagnostic(), &err).raise()
     })
 }
 
@@ -351,7 +354,7 @@ struct AssemblerCommand {
 
 /// Additional resources used by optimize_and_codegen (not module specific)
 #[derive(Clone)]
-pub struct CodegenContext {
+pub struct CodegenContext<'ll> {
     // Resources needed when running LTO
     pub time_passes: bool,
     pub lto: Lto,
@@ -393,9 +396,12 @@ pub struct CodegenContext {
     time_graph: Option<TimeGraph>,
     // The assembler command if no_integrated_as option is enabled, None otherwise
     assembler_cmd: Option<Arc<AssemblerCommand>>,
+    // This field is used to give a lifetime parameter to the struct so that it can implement
+    // the Backend trait.
+    phantom: PhantomData<&'ll ()>
 }
 
-impl CodegenContext {
+impl CodegenContext<'ll> {
     pub fn create_diag_handler(&self) -> Handler {
         Handler::with_emitter(true, false, Box::new(self.diag_emitter.clone()))
     }
@@ -423,13 +429,40 @@ pub(crate) fn save_temp_bitcode(&self, module: &ModuleCodegen, name: &str) {
     }
 }
 
+impl<'ll> Backend for CodegenContext<'ll> {
+    type Value = &'ll Value;
+    type BasicBlock = &'ll BasicBlock;
+    type Type = &'ll Type;
+    type Context = &'ll llvm::Context;
+}
+
+impl CommonWriteMethods for CodegenContext<'ll> {
+    fn val_ty(&self, v: &'ll Value) -> &'ll Type {
+        common::val_ty(v)
+    }
+
+    fn c_bytes_in_context(&self, llcx: &'ll llvm::Context, bytes: &[u8]) -> &'ll Value {
+        common::c_bytes_in_context(llcx, bytes)
+    }
+
+    fn c_struct_in_context(
+        &self,
+        llcx: &'a llvm::Context,
+        elts: &[&'a Value],
+        packed: bool,
+    ) -> &'a Value {
+        common::c_struct_in_context(llcx, elts, packed)
+    }
+}
+
+
 pub struct DiagnosticHandlers<'a> {
-    data: *mut (&'a CodegenContext, &'a Handler),
+    data: *mut (&'a CodegenContext<'a>, &'a Handler),
     llcx: &'a llvm::Context,
 }
 
 impl<'a> DiagnosticHandlers<'a> {
-    pub fn new(cgcx: &'a CodegenContext,
+    pub fn new(cgcx: &'a CodegenContext<'a>,
                handler: &'a Handler,
                llcx: &'a llvm::Context) -> Self {
         let data = Box::into_raw(Box::new((cgcx, handler)));
@@ -455,7 +488,7 @@ fn drop(&mut self) {
 unsafe extern "C" fn report_inline_asm<'a, 'b>(cgcx: &'a CodegenContext,
                                                msg: &'b str,
                                                cookie: c_uint) {
-    cgcx.diag_emitter.inline_asm_error(cookie as u32, msg.to_string());
+    cgcx.diag_emitter.inline_asm_error(cookie as u32, msg.to_owned());
 }
 
 unsafe extern "C" fn inline_asm_handler(diag: &SMDiagnostic,
@@ -884,10 +917,10 @@ unsafe fn embed_bitcode(cgcx: &CodegenContext,
                         llcx: &llvm::Context,
                         llmod: &llvm::Module,
                         bitcode: Option<&[u8]>) {
-    let llconst = C_bytes_in_context(llcx, bitcode.unwrap_or(&[]));
+    let llconst = cgcx.c_bytes_in_context(llcx, bitcode.unwrap_or(&[]));
     let llglobal = llvm::LLVMAddGlobal(
         llmod,
-        val_ty(llconst),
+        cgcx.val_ty(llconst),
         "rustc.embedded.module\0".as_ptr() as *const _,
     );
     llvm::LLVMSetInitializer(llglobal, llconst);
@@ -904,10 +937,10 @@ unsafe fn embed_bitcode(cgcx: &CodegenContext,
     llvm::LLVMRustSetLinkage(llglobal, llvm::Linkage::PrivateLinkage);
     llvm::LLVMSetGlobalConstant(llglobal, llvm::True);
 
-    let llconst = C_bytes_in_context(llcx, &[]);
+    let llconst = cgcx.c_bytes_in_context(llcx, &[]);
     let llglobal = llvm::LLVMAddGlobal(
         llmod,
-        val_ty(llconst),
+        cgcx.val_ty(llconst),
         "rustc.embedded.cmdline\0".as_ptr() as *const _,
     );
     llvm::LLVMSetInitializer(llglobal, llconst);
@@ -1440,15 +1473,12 @@ fn execute_copy_from_cache_work_item(cgcx: &CodegenContext,
                module.name,
                source_file,
                obj_out.display());
-        match link_or_copy(&source_file, &obj_out) {
-            Ok(_) => { }
-            Err(err) => {
-                let diag_handler = cgcx.create_diag_handler();
-                diag_handler.err(&format!("unable to copy {} to {}: {}",
-                                          source_file.display(),
-                                          obj_out.display(),
-                                          err));
-            }
+        if let Err(err) = link_or_copy(&source_file, &obj_out) {
+            let diag_handler = cgcx.create_diag_handler();
+            diag_handler.err(&format!("unable to copy {} to {}: {}",
+                                      source_file.display(),
+                                      obj_out.display(),
+                                      err));
         }
     }
 
@@ -1617,6 +1647,7 @@ fn start_executing_work(tcx: TyCtxt,
         target_pointer_width: tcx.sess.target.target.target_pointer_width.clone(),
         debuginfo: tcx.sess.opts.debuginfo,
         assembler_cmd,
+        phantom: PhantomData
     };
 
     // This is the "main loop" of parallel work happening for parallel codegen.
@@ -2111,7 +2142,7 @@ fn maybe_start_llvm_timer(config: &ModuleConfig,
 const LLVM_WORK_PACKAGE_KIND: time_graph::WorkPackageKind =
     time_graph::WorkPackageKind(&["#7DB67A", "#C6EEC4", "#ACDAAA", "#579354", "#3E6F3C"]);
 
-fn spawn_work(cgcx: CodegenContext, work: WorkItem) {
+fn spawn_work(cgcx: CodegenContext<'static>, work: WorkItem) {
     let depth = time_depth();
 
     thread::spawn(move || {