]> git.lizzy.rs Git - rust.git/commitdiff
rustc_codegen_llvm: use safe references for Context and Module.
authorIrina Popa <irinagpopa@gmail.com>
Wed, 27 Jun 2018 14:57:25 +0000 (17:57 +0300)
committerIrina Popa <irinagpopa@gmail.com>
Mon, 30 Jul 2018 15:27:52 +0000 (18:27 +0300)
13 files changed:
src/librustc_codegen_llvm/allocator.rs
src/librustc_codegen_llvm/back/lto.rs
src/librustc_codegen_llvm/back/write.rs
src/librustc_codegen_llvm/base.rs
src/librustc_codegen_llvm/common.rs
src/librustc_codegen_llvm/context.rs
src/librustc_codegen_llvm/debuginfo/metadata.rs
src/librustc_codegen_llvm/debuginfo/mod.rs
src/librustc_codegen_llvm/debuginfo/utils.rs
src/librustc_codegen_llvm/lib.rs
src/librustc_codegen_llvm/llvm/ffi.rs
src/librustc_codegen_llvm/llvm/mod.rs
src/librustc_codegen_llvm/type_.rs

index 49cdbf34fa95a6ac19e95e30a13ac2654eb78032..2d401da958b13fa6465af1612a64b95774198862 100644 (file)
@@ -20,8 +20,8 @@
 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),
index 93cb9eb9767657ed32bc876b828dd17bfe8ac06c..fce34710b814302a94a2c24eb0225ee9705ac07e 100644 (file)
@@ -14,7 +14,7 @@
 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 @@ pub(crate) unsafe fn optimize(&mut self,
         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 @@ unsafe fn optimize(&mut self, cgcx: &CodegenContext, timeline: &mut Timeline)
         // 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 @@ unsafe fn optimize(&mut self, cgcx: &CodegenContext, timeline: &mut Timeline)
             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)
     }
index d36142af56c6540ad15af51d052e1bace989f8c9..f5c2ca22ec8563dc0bb908f259f09569a4484706 100644 (file)
@@ -26,8 +26,8 @@
 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<dyn Fn() -> Result<TargetMachineRef, String> + Send + Sync>
+    -> Arc<dyn Fn() -> 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<ModuleConfig>,
     metadata_module_config: Arc<ModuleConfig>,
     allocator_module_config: Arc<ModuleConfig>,
-    pub tm_factory: Arc<dyn Fn() -> Result<TargetMachineRef, String> + Send + Sync>,
+    pub tm_factory: Arc<dyn Fn() -> 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 @@ pub(crate) fn save_temp_bitcode(&self, module: &ModuleCodegen, name: &str) {
             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 @@ pub(crate) fn save_temp_bitcode(&self, module: &ModuleCodegen, name: &str) {
 
 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<CompiledModule, FatalError>
 {
     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<F, R>(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<F, R>(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 @@ extern "C" fn demangle_callback(input_ptr: *const c_char,
 /// 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
     }
index 223c04f420f3ff978576cf7f7ad044a4faf9cd37..c4fb251c5f42c208e4aedf012908f784493074d4 100644 (file)
@@ -30,8 +30,8 @@
 
 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::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 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 create_entry_fn<'cx>(cx: &'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 @@ enum MetadataKind {
     }).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 @@ enum MetadataKind {
         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 @@ fn next(&mut self) -> Option<ValueRef> {
     }
 }
 
-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 module_codegen<'a, '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 module_codegen<'a, '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,
+        })
     }
 }
 
index 60bba635a7887bbe48fb81a5759eb8bca833fb13..be948442707c1dd5de3af95700a0e03f74b8cbc9 100644 (file)
@@ -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);
index 130e14c976dee2817cacb1125838425c505843f4..f91173226c48d4bad7e9a828fde7dc1c60816d9a 100644 (file)
@@ -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;
 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<Stats>,
     pub codegen_unit: Arc<CodegenUnit<'tcx>>,
 
@@ -94,7 +94,7 @@ pub struct CodegenCx<'a, 'tcx: 'a> {
     pub pointee_infos: RefCell<FxHashMap<(Ty<'tcx>, Size), Option<PointeeInfo>>>,
     pub isize_ty: Type,
 
-    pub dbg_cx: Option<debuginfo::CrateDebugContext<'tcx>>,
+    pub dbg_cx: Option<debuginfo::CrateDebugContext<'a, 'tcx>>,
 
     eh_personality: Cell<Option<ValueRef>>,
     eh_unwind_resume: Cell<Option<ValueRef>>,
@@ -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<CodegenUnit<'tcx>>,
-               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 @@ pub fn new(tcx: TyCtxt<'a, 'tcx, '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),
+        }
     }
 }
 
index 59c14a6910ba2f896d0feefb9ca37cf49da77199..e7a6dc452221462c0634b89ec3af0a8151bb2cc7 100644 (file)
@@ -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,
index fcabd27332654c71cb4f359124fc7a4607f7017f..d4b5110603369b4385cf2b1ee4552e1812fcfc53 100644 (file)
@@ -21,7 +21,7 @@
 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_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<FxHashMap<(Symbol, Symbol), DIFile>>,
     created_enum_disr_types: RefCell<FxHashMap<(DefId, layout::Primitive), DIType>>,
@@ -82,8 +82,8 @@ pub struct CrateDebugContext<'tcx> {
     composite_types_completed: RefCell<FxHashSet<DIType>>,
 }
 
-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
index 87da33166286ff4bdb2157cd99c07cb5344edfdd..85cddb0a580a58731854626f907135b75e5dd42b 100644 (file)
@@ -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()
 }
 
index 0b5524990e89c53191984f2ef4103dade8a8cf35..724a2e3e65f4247a7a12c6936af79e58638fb46c 100644 (file)
 
 #![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 _));
         }
     }
 }
index 6e61b327f1d796241612fc97c53c1be8100d9f90..9d94869dab06e85e2d0c32387d66d7ecace9585a 100644 (file)
@@ -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 @@ pub enum ThreadLocalMode {
 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 @@ pub struct DIFlags: ::libc::uint32_t {
 #[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 @@ pub fn LLVMFunctionType(ReturnType: TypeRef,
     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 @@ pub fn LLVMStructTypeInContext(C: ContextRef,
     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 @@ pub fn LLVMStructTypeInContext(C: ContextRef,
     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 @@ pub fn LLVMRustConstInt128Get(ConstantVal: ValueRef, SExt: bool,
 
 
     // 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 @@ pub fn LLVMConstInlineAsm(Ty: TypeRef,
 
 
     // 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 @@ pub fn LLVMConstInlineAsm(Ty: TypeRef,
 
     // 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 @@ pub fn LLVMConstInlineAsm(Ty: TypeRef,
     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 @@ pub fn LLVMRustAddFunctionAttrStringValue(Fn: ValueRef,
     // 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 @@ pub fn LLVMAddIncoming(PhiNode: ValueRef,
                            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 @@ pub fn LLVMRustBuildAtomicFence(B: BuilderRef,
     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 @@ pub fn LLVMRustBuildAtomicFence(B: BuilderRef,
     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 @@ pub fn LLVMRustPassManagerBuilderPopulateThinLTOPassManager(
     /// 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 @@ pub fn LLVMRustInlineAsm(Ty: TypeRef,
     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 @@ pub fn LLVMRustDICompositeTypeSetTypeArray(Builder: DIBuilderRef,
                                                TypeArray: DIArray);
 
 
-    pub fn LLVMRustDIBuilderCreateDebugLocation(Context: ContextRef,
+    pub fn LLVMRustDIBuilderCreateDebugLocation(Context: &Context,
                                                 Line: c_uint,
                                                 Column: c_uint,
                                                 Scope: DIScope,
@@ -1618,11 +1614,11 @@ pub fn LLVMRustCreateTargetMachine(Triple: *const c_char,
                                        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 @@ pub fn LLVMRustConfigurePassManagerBuilder(PMB: PassManagerBuilderRef,
                                                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 @@ pub fn LLVMRustPrintModule(PM: PassManagerRef,
                                                    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 @@ pub fn LLVMRustPrintModule(PM: PassManagerRef,
 
     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 @@ pub fn LLVMRustUnpackInlineAsmDiagnostic(DI: DiagnosticInfoRef,
     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 @@ pub fn LLVMRustArchiveMemberNew(Filename: *const c_char,
                                     -> 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 @@ pub fn LLVMRustBuildOperandBundleDef(Name: *const c_char,
 
     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 @@ pub fn LLVMRustCreateThinLTOData(
     ) -> *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;
index b6ff9b17bd93394a5ab60492de501580105a92e1..75f13e888586602eb72a043cc8184ee89f07586d 100644 (file)
@@ -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));
     }
index 37157635b2d67578f94cf30ffb6d301cb317f96a..cb77ce0039756020d941ab60efda17a81b1cfce0 100644 (file)
@@ -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 @@ pub fn i8(cx: &CodegenCx) -> 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 @@ pub fn ix(cx: &CodegenCx, num_bits: u64) -> 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 @@ pub fn i8p(cx: &CodegenCx) -> 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()
     }