我正在查看由clang从cpp文件转换的llvm ir文件。但是我发现llvm ir文件中有几个函数只有声明没有定义。所有这些功能都不是“内置”功能,如:
declare i32 @puts(i8* nocapture)
就像:
declare void @_ZNK5Arrow7BaseRow9getColumnINS_11IpGenPrefixEEEvtRT_(%"class.Arrow::BaseRow"*, i16 zeroext, %"class.Arrow::IpGenPrefix"* dereferenceable(24)) #0
似乎这些功能正在使用一些外部定义?我是LLVM IR的新手。我想知道LLVM IR有没有像cpp库那样的方式,我可以存储我将在一些LLVM IR库中使用的函数,并通过像include这样的东西在.ll文件中使用它们?
由于
答案 0 :(得分:1)
似乎那些函数正在使用一些外部定义?
完全。 declare
关键字indicates一个函数声明,而不是函数定义和函数声明can only be linked externally:
函数声明具有除external或extern_weak之外的任何链接类型是非法的。
Clang生成声明而非定义的原因(很可能)是这些函数未在给定的转换单元中定义。
声明在链接期间解决。要将多个LLVM模块链接在一起,请使用llvm-link工具。
例如,假设lib.cpp
定义foo()
中使用的函数main.cpp
。
$ clang++ -c -emit-llvm main.cpp lib.cpp
此命令将这些文件编译为LLVM IR,并创建两个模块main.bc
和lib.bc
。 main.bc
只包含foo()
的声明,因为此函数是在单独的翻译单元中定义的。 foo()
的定义位于lib.bc
。
$ llvm-link main.bc lib.bc -o all.bc
此命令将main.bc
和lib.bc
链接到一个模块,该模块现在包含foo()
的定义。