c++ - clang:使用 O3 导出隐式实例化函数的符号

标签 c++ linker clang llvm llvm-c++-api

TL,DR:即使 -O3 处于事件状态,我如何强制 clang 导出隐式实例化函数的符号?

让我们看下面的代码:

#include <iostream>
#include <llvm/Support/DynamicLibrary.h>
#include <llvm/ExecutionEngine/ExecutionEngine.h>
#include <llvm/ExecutionEngine/RTDyldMemoryManager.h>

template <typename T>
__attribute__((noinline))
int twice(const T& t) {
    return t * 2;
}

int thrice(const int& t) {
    return t * 3;
}

int main() {
    std::cout << twice(5) << std::endl;
    std::cout << thrice(5) << std::endl;

    llvm::sys::DynamicLibrary::LoadLibraryPermanently(nullptr);  // Make symbols from current process visible
    std::cout << "address of twice: " << llvm::RTDyldMemoryManager::getSymbolAddressInProcess("__Z5twiceIiEiRKT_") << std::endl;
    std::cout << "address of thrice: " << llvm::RTDyldMemoryManager::getSymbolAddressInProcess("__Z6thriceRKi") << std::endl;
}

有两个函数,两次和三次。第一个是模板化的,第二个不是。我首先定期给他们打电话,然后尝试使用 libLLVM 获取他们的地址。将其视为 super 简化的 JIT 编译器的一部分(它有一个名称出现的 mangler)。

使用 clang++ -O0 -I/usr/local/opt/llvm/include -L/usr/local/opt/llvm/lib/jit.cpp -lLLVM(clang 版本 6.0.0在 OS X 上),输出符合预期:

10
15
address of twice: 4350763184
address of thrice: 4350762224

如果启用优化,twice 的符号将不再导出,如 nm a.out | 中所示grep 两次:

00000001000010b0 T __Z5twiceIiEiRKT_ (with -O0)
00000001000009c0 t __Z5twiceIiEiRKT_ (with -O3)

因此,libLLVM 不再找到该函数:

10
15
address of twice: 0
address of thrice: 4315621072

使用 gcc,符号被导出。

如果我显式实例化它,我可以让 clang 导出符号:

template int twice<int>(const int& t);

然而,这并不是一个真正的选择,因为我们不知道 JIT 引擎将调用哪些实例化。

我知道 this post ,但它只处理显式实例化。

最佳答案

添加属性used,像这样:

template <typename T>
__attribute__((used))
int twice(const T& t) {
    return t * 2;
}

这将强制 Clang 导出符号。

关于c++ - clang:使用 O3 导出隐式实例化函数的符号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52211379/

相关文章:

c++ - 在 Linux 中获取主目录

c++ - 使用 openCV 时如何修复链接器错误?

clang - 如何使用 Clang 获取当前版本的 AST?

gcc - 如何使用 Homebrew 软件和 gcc-4.9 构建 openmpi?

c++ - Cocos2d-x box2d applyforce方向

c++ - 转发构造函数调用 2 次基类的复制构造函数

windows - 如何编译这个程序?链接器阶段错误

c - 对 `writen' 的 undefined reference

c++ - cmake find_package 指定路径

objective-c - __attribute__ ((deprecated)) 不适用于 objective-c 协议(protocol)方法?