diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index 51b0299e63f..6c2601bf1ef 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -363,6 +363,10 @@ extern { pub type ThinLTOData; } /// LLVMRustThinLTOBuffer extern { pub type ThinLTOBuffer; } +// LLVMRustModuleNameCallback +pub type ThinLTOModuleNameCallback = + unsafe extern "C" fn(*mut c_void, *const c_char, *const c_char); + /// LLVMRustThinLTOModule #[repr(C)] pub struct ThinLTOModule { @@ -1622,6 +1626,11 @@ extern "C" { Data: &ThinLTOData, Module: &Module, ) -> bool; + pub fn LLVMRustGetThinLTOModuleImports( + Data: *const ThinLTOData, + ModuleNameCallback: ThinLTOModuleNameCallback, + CallbackPayload: *mut c_void, + ); pub fn LLVMRustFreeThinLTOData(Data: &'static mut ThinLTOData); pub fn LLVMRustParseBitcodeForThinLTO( Context: &Context, diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index 09befdaae37..5c4bb61781e 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -1123,6 +1123,28 @@ 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()); + } + } +} + // This struct and various functions are sort of a hack right now, but the // problem is that we've got in-memory LLVM modules after we generate and // optimize all codegen-units for one compilation in rustc. To be compatible @@ -1288,6 +1310,11 @@ LLVMRustPrepareThinLTOImport(const LLVMRustThinLTOData *Data, LLVMModuleRef M) { report_fatal_error("ThinLTO not available"); } +extern "C" LLVMRustThinLTOModuleImports +LLVMRustGetLLVMRustThinLTOModuleImports(const LLVMRustThinLTOData *Data) { + report_fatal_error("ThinLTO not available"); +} + extern "C" void LLVMRustFreeThinLTOData(LLVMRustThinLTOData *Data) { report_fatal_error("ThinLTO not available");