在LLVM中,我们有LLVMContext
,它是存储单元,还有llvm::Module
,它是构建新符号(函数和类型)的地方。
我的问题是;什么是用于编译单元的正确llvm抽象?是Module
吗?或者这实际上是为了更大的范围,即:共享库目标
在我看来,一个编译单元必须满足要么全有要么全无的结果;要么它编译了所有内容而没有错误,要么存在错误并且需要在CU中的任何符号可用之前重新修复和构建它。在我看来,这就是编译单元应该代表的定义
如果模块是CU的正确抽象,我如何将其他(正确编译的)Module
对象中的符号呈现给即将构建的新模块,以便它能够找到这些符号?我需要添加申报单吗?或者有其他快捷方式吗?
指向clang
中的相关线的点将对
模块是编译单元的正确抽象。您可以将模块链接在一起,从那里进行整个程序分析。
这是一个正在进行的尝试,旨在回答我自己的问题:
类llvm::Linker
能够获取多个模块,并返回包含现有模块中所有符号的单个复合模块。在链接完成并创建了复合模块之后,我仍然不清楚关于输入模块所有权的规则是什么。
在任何情况下,类都应该允许您采用增量路径来增长模块。假设您正在尝试实现REPL,这意味着您向全局名称空间添加新的符号:
REPL的大纲如下:
- 在REPL中编写一些函数
- 将函数编译为单个模块,称之为"base"
- 在REPL中再写一些函数
- 在新模块中编译新函数
- 如果新的函数模块编译成功,则链接"base"和新模块中的新模块,称其为"base"。2
冲洗并重复
如果按名称替换符号或函数,则希望较旧的符号显示符号的替代版本。因此,当您定义一个新函数时,需要确保在现有的"基本"模块和新的模块中都调用了
getOrInsertFunction
。