模块结构
LLVM程序是由若干的模块(Module)组成,每个模块中包含有一些函数、全局变量和符号表。 这些模块可能由LLVM的连接器组合在一起,组合的过程将会整合这些函数和全局变量的定义,整合他们的符号表。
连接类型
所有的全局变量和函数都有一个伴随它的连接类型,将会有以下几种:
- private。当变量被声明为private连接类型时,这个变量将只能被它所在的模块所调用。当连接一个模块时,模块中被声明为private连接类型的变量可能会被改名,并且该变量将不会出现在object文件的符号表中。
- internal。与private行为类似,但变量将会以本地符号(ELF格式下的STB_LOCAL)的形式出现object文件中。
- available_externally。 该类型的全局值,将不会出现在object文件当中。从连接器的角度看,一个available_externally等价于一个外部声明。允许包括内联在内的优化行为。值得注意的是,这种类型只能被定义,不可被声明。
- linkonce。 当连接器工作时,将会把该类型的全局值与其他与之同名的全局值合并。它常被用于内联函数、模板等方面。
- weak。 与linkonce类似,都会与其他与之同名的全局值进行合并,但未引用的带weak标识的全局值可能会被抛弃。
- common。 与weak类似,但常用于C语言中暂定的变量定义。带有common的全局值和带有weak符号的全局值合并的方式相同,但即使没有被引用也不会被删除。common可能不会有一个明确的部分,但必须初始化为0,且不可能被标志为constant。函数和切片不可以带有common标识。
- appending。 只能用于数组类型的全局指针变量。
- extern_weak。 遵循ELF对象文件模型:除非被链接,否则带有extern_weak的符号都是weak的但如果没有被链接,那该符号会变成null而不是未定义引用。
- linkonce_odr, weak_odr。 某些语言允许不同的全局值被合并,这些语言可以使用这两个链接标识表明全局值将只与等下批的全局值合并。
- external。 如果上述标识符都没有被使用,那么该全局值是外部可见的。这意味着它参与链接,可以用于处理外部符号引用。
值得注意的是 函数只能拥有 external 或 extern_weak 两种链接标识。