about summary refs log tree commit diff
path: root/src/rustllvm/PassWrapper.cpp
diff options
context:
space:
mode:
authorMichael Woerister <michaelwoerister@posteo>2018-07-16 08:57:49 +0200
committerMichael Woerister <michaelwoerister@posteo>2018-07-16 08:57:49 +0200
commitb822e699c3e811f929fd69046095c1d6eb9abd22 (patch)
treed18fec3f7882dca43be036aa8dde18d5f4acf227 /src/rustllvm/PassWrapper.cpp
parent99140df0bd5a4dd77db28d78e73df4b5f6ba79a6 (diff)
downloadrust-b822e699c3e811f929fd69046095c1d6eb9abd22.tar.gz
rust-b822e699c3e811f929fd69046095c1d6eb9abd22.zip
Revert "Use callback-based interface to load ThinLTO import data into rustc."
This reverts commit e045a6cd8c0235a26ef11e6cd9a13ebd817f1265.
Diffstat (limited to 'src/rustllvm/PassWrapper.cpp')
-rw-r--r--src/rustllvm/PassWrapper.cpp67
1 files changed, 47 insertions, 20 deletions
diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp
index 1f96b9042ba..30f585efedc 100644
--- a/src/rustllvm/PassWrapper.cpp
+++ b/src/rustllvm/PassWrapper.cpp
@@ -798,6 +798,11 @@ LLVMRustPGOAvailable() {
 #endif
 }
 
+// We encode the ThinLTO module import map as a nested null-terminated list to
+// get it into Rust.
+typedef const char* LLVMRustThinLTOModuleName;
+typedef LLVMRustThinLTOModuleName* LLVMRustThinLTOModuleImports;
+
 #if LLVM_VERSION_GE(4, 0)
 
 // Here you'll find an implementation of ThinLTO as used by the Rust compiler
@@ -1099,28 +1104,50 @@ LLVMRustPrepareThinLTOImport(const LLVMRustThinLTOData *Data, LLVMModuleRef M) {
   return true;
 }
 
-extern "C" typedef void (*LLVMRustModuleNameCallback)(void*, // payload
-                                                      const char*, // importing module name
-                                                      const char*); // imported module name
-
-// Calls `module_name_callback` for each module import done by ThinLTO.
-// The callback is provided with regular null-terminated C strings.
-extern "C" void
-LLVMRustGetThinLTOModuleImports(const LLVMRustThinLTOData *data,
-                                LLVMRustModuleNameCallback module_name_callback,
-                                void* callback_payload) {
-  for (const auto& importing_module : data->ImportLists) {
-    const std::string importing_module_id = importing_module.getKey().str();
-
-    const auto& imports = importing_module.getValue();
-
-    for (const auto& imported_module : imports) {
-      const std::string imported_module_id = imported_module.getKey().str();
-      module_name_callback(callback_payload,
-                           importing_module_id.c_str(),
-                           imported_module_id.c_str());
+/// Converts the LLVMRustThinLTOData::ImportLists map into a nested list. The
+/// first level is a null-terminated array with an entry for each module. Each
+/// entry is a pointer that points to a null-termined array of module names. The
+/// first entry is always the name of the *importing* module, the following
+/// entries are  the names of the modules it imports from. Each module name is
+/// a regular C string.
+extern "C" LLVMRustThinLTOModuleImports*
+LLVMRustGetThinLTOModuleImports(const LLVMRustThinLTOData *Data) {
+  // Allocate number of module +1. This is a null-terminated array.
+  LLVMRustThinLTOModuleImports* thinLTOModuleImports =
+    new LLVMRustThinLTOModuleImports[Data->ImportLists.size() + 1];
+  size_t module_index = 0;
+
+  for (const auto & module : Data->ImportLists) {
+    StringRef module_id = module.getKey();
+    const auto& imports = module.getValue();
+
+    // Allocate number of imported module + 2, one extra for the name of the
+    // importing module and another one for null-termination.
+    LLVMRustThinLTOModuleImports imports_array =
+      new LLVMRustThinLTOModuleName[imports.size() + 2];
+
+    // The first value is always the name of the *importing* module.
+    imports_array[0] = strndup(module_id.data(), module_id.size());
+
+    size_t imports_array_index = 1;
+    for (const auto imported_module_id : imports.keys()) {
+      // The following values are the names of the imported modules.
+      imports_array[imports_array_index] = strndup(imported_module_id.data(),
+                                                   imported_module_id.size());
+      imports_array_index += 1;
     }
+
+    assert(imports_array_index == imports.size() + 1);
+    imports_array[imports_array_index] = nullptr;
+
+    thinLTOModuleImports[module_index] = imports_array;
+    module_index += 1;
   }
+
+  assert(module_index == Data->ImportLists.size());
+  thinLTOModuleImports[module_index] = nullptr;
+
+  return thinLTOModuleImports;
 }
 
 // This struct and various functions are sort of a hack right now, but the