summary refs log tree commit diff
path: root/src/librustc_codegen_llvm/back
diff options
context:
space:
mode:
authorMichael Woerister <michaelwoerister@posteo>2018-07-13 12:41:22 +0200
committerMichael Woerister <michaelwoerister@posteo>2018-07-13 12:41:22 +0200
commite045a6cd8c0235a26ef11e6cd9a13ebd817f1265 (patch)
tree074eeb68c416a178d201373ae32957d14c45111a /src/librustc_codegen_llvm/back
parentdd3f445ed264ffc09ea42bd8d89853242e3a26f4 (diff)
downloadrust-e045a6cd8c0235a26ef11e6cd9a13ebd817f1265.tar.gz
rust-e045a6cd8c0235a26ef11e6cd9a13ebd817f1265.zip
Use callback-based interface to load ThinLTO import data into rustc.
Diffstat (limited to 'src/librustc_codegen_llvm/back')
-rw-r--r--src/librustc_codegen_llvm/back/lto.rs74
1 files changed, 31 insertions, 43 deletions
diff --git a/src/librustc_codegen_llvm/back/lto.rs b/src/librustc_codegen_llvm/back/lto.rs
index a68f22b2651..55499552f5c 100644
--- a/src/librustc_codegen_llvm/back/lto.rs
+++ b/src/librustc_codegen_llvm/back/lto.rs
@@ -805,7 +805,7 @@ pub struct ThinLTOImports {
 
 impl ThinLTOImports {
 
-    pub fn new_empty() -> ThinLTOImports {
+    pub fn new() -> ThinLTOImports {
         ThinLTOImports {
             imports: FxHashMap(),
         }
@@ -813,58 +813,46 @@ impl ThinLTOImports {
 
     /// Load the ThinLTO import map from ThinLTOData.
     unsafe fn from_thin_lto_data(data: *const llvm::ThinLTOData) -> ThinLTOImports {
-        let raw_data: *const llvm::ThinLTOModuleImports =
-            llvm::LLVMRustGetThinLTOModuleImports(data);
 
-        assert!(!raw_data.is_null());
-
-        let mut imports = FxHashMap();
-        let mut module_ptr = raw_data;
-        let mut module_index = 0;
-
-        loop {
-            let mut entry_ptr: *const llvm::ThinLTOModuleName = *module_ptr;
-
-            if entry_ptr.is_null() {
-                break;
+        fn module_name_to_str(c_str: &CStr) -> &str {
+            match c_str.to_str() {
+                Ok(s) => s,
+                Err(e) => {
+                    bug!("Encountered non-utf8 LLVM module name `{}`: {}",
+                        c_str.to_string_lossy(),
+                        e)
+                }
             }
+        }
 
-            let importing_module_name = CStr::from_ptr(*entry_ptr)
-                .to_str()
-                .expect("Non-utf8 LLVM module name encountered")
-                .to_owned();
-
-            entry_ptr = entry_ptr.offset(1);
-
-            let mut imported_modules = vec![];
-
-            loop {
-                let imported_module_name = *entry_ptr;
-
-                if imported_module_name.is_null() {
-                    break
-                }
+        unsafe extern "C" fn imported_module_callback(payload: *mut libc::c_void,
+                                                      importing_module_name: *const libc::c_char,
+                                                      imported_module_name: *const libc::c_char) {
+            let map = &mut* (payload as *mut ThinLTOImports);
 
-                let imported_module_name = CStr::from_ptr(imported_module_name)
-                    .to_str()
-                    .expect("Non-utf8 LLVM module name encountered")
-                    .to_owned();
+            let importing_module_name = CStr::from_ptr(importing_module_name);
+            let importing_module_name = module_name_to_str(&importing_module_name);
+            let imported_module_name = CStr::from_ptr(imported_module_name);
+            let imported_module_name = module_name_to_str(&imported_module_name);
 
-                imported_modules.push(imported_module_name);
-                entry_ptr = entry_ptr.offset(1);
+            if !map.imports.contains_key(importing_module_name) {
+                map.imports.insert(importing_module_name.to_owned(), vec![]);
             }
 
-            imports.insert(importing_module_name, imported_modules);
-
-            module_ptr = module_ptr.offset(1);
-            module_index += 1;
+            map.imports
+               .get_mut(importing_module_name)
+               .unwrap()
+               .push(imported_module_name.to_owned());
         }
 
-        assert_eq!(module_index, imports.len());
+        let mut map = ThinLTOImports {
+            imports: FxHashMap(),
+        };
 
-        ThinLTOImports {
-            imports
-        }
+        llvm::LLVMRustGetThinLTOModuleImports(data,
+                                              imported_module_callback,
+                                              &mut map as *mut _ as *mut libc::c_void);
+        map
     }
 
     pub fn save_to_file(&self, path: &Path) -> io::Result<()> {