I'm trying to implement a module system in my programming language. I've read the docs (https://llvm.org/doxygen/classllvm_1_1Linker.html) and the linkModules() function is exactly what I need. When linking two modules I'm getting a weird error message. I don't get what I'm doing wrong.
export.mylang:
export func eoeo(x: i32) -> void {}
import.mylang:
import "@project/eo.mylang";
func main() -> i32 {
return 0;
}
by the way, import.mylang doesn't even call to eoeo() ...
Then I use linkModules() to glue the two modules together:
llvm::Linker::linkModules(*mylang::CompilationUnits[mylang::CompilationUnits.size() - 2]->Module,
std::unique_ptr<llvm::Module>(mylang::CompilationUnits.back()->Module));
this code generates the following LLVM IR (after connecting the two modules):
define void @eoeo(i32 %x) {
entry:
%x1 = alloca i32, align 4
store i32 %x, i32* %x1, align 4
ret void
}
define i32 @main() {
entry:
ret i32 0
}
And in my terminal I see this error message:
Function context does not match Module context!
void (i32)* @eoeo
What does that even mean? Yeah, the two modules do have different contexts, but isn't linkModules() supposed to glue them together into a single large module (regardless of different contexts)? I'm so confused.
(I'm writing this an hour later). So I've tried to call eoeo() and my source file did compile but I was left with a weird error message:
Call parameter type does not match function signature!
i32 3
i32 call void @eoeo(i32 3)
Function context does not match Module context!
void (i32)* @eoeo
Call parameter type does not match function signature!
i32 3
i32 call void @eoeo(i32 3)
So now I guess types are scoped to an LLVM context?
How can I simply take one module and put it's stuff into another module without worrying about contexts? What's interesting is that I can not define but declare a function in a module (without the body) and then have the body defined in a different module. then I can dump these modules to .ll files and use the llvm-link command line tool to link them (everything works). The thing is that I really don't want to deal with the file system and use std::system() to interact with LLVM's tools. It does work, but it's tedious to deal with file paths manually.
LLVMContextto manage some memory and resources: it owns some global data, such as types and constants. In consequence, within the sameLLVMContext, the same LLVMTypewill have the same memory address allocated. With the file formats, there is noLLVMContextinvolved. llvm-link loads the modules in the sameLLVMContextto link them.std::system. You could either use a singleLLVMContextif your application has a single-thread for compilation. Or use oneLLVMContextper thread, serialize the Modules into temporary files, and reload them in the sameLLVMContextto link them.