我一直在试图建立和执行LLVM模块重整混乱。我的代码生成模块很长,所以我不会在这里发布。相反,我的问题是关于Clang和LLVM如何共同实现名称修改。我将解释我的具体问题来激发这个问题。名称在LLVM
这里是我的LLVM模块之一的源代码:
#include <iostream>
int main() {
std::cout << "Hello, world. " << std::endl;
return 0;
}
Here is the generated LLVM IR;它对于StackOverflow来说太大了。
当我尝试使用lli
我的模块来执行,我得到以下错误:
LLVM ERROR: Program used external function '__ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEC1Emc' which could not be resolved!
通过demangler运行符号,缺少的标志是:
_std::__1::basic_string, std::__1::allocator >::basic_string(unsigned long, char)
额外_
是可疑,而且没有主导下划线的功能似乎存在于IR中!
; Function Attrs: alwaysinline ssp uwtable
define available_externally hidden void @_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEC1Emc(%"class.std::__1::basic_string"*, i64, i8 signext) unnamed_addr #2 align 2 {
%4 = alloca %"class.std::__1::basic_string"*, align 8
%5 = alloca i64, align 8
%6 = alloca i8, align 1
store %"class.std::__1::basic_string"* %0, %"class.std::__1::basic_string"** %4, align 8
store i64 %1, i64* %5, align 8
store i8 %2, i8* %6, align 1
%7 = load %"class.std::__1::basic_string"*, %"class.std::__1::basic_string"** %4, align 8
%8 = load i64, i64* %5, align 8
%9 = load i8, i8* %6, align 1
call void @_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEC2Emc(%"class.std::__1::basic_string"* %7, i64 %8, i8 signext %9)
ret void
}
我在MacOS,所以前面的下划线是可以预料的,但我认为锵可能会增加它两次。
我通过LLVM/Clang的来源看,似乎有两个重整步骤:
- 考虑可能重载C++函数和重整他们唯一的名称为LLVM IR
- 隔空错位从LLVM IR的名称和添加任何特定于平台的怪癖,如领先的下划线
但是,这只是我的理论。有人可以解释Clang和LLVM中的加工过程是如何工作的吗?我应该如何创建我的llvm::DataLayout
对象才能为我的平台获得正确的绑定?
nm -gU /usr/lib/libc++.dylib
和nm -gU /usr/lib/libc++abi.dylib
不包含__ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEC1Emc
当我试图编译IR,我得到这个错误:
llc generated.ll
clang++ generated.s
Undefined symbols for architecture x86_64: "std::__1::basic_string, std::__1::allocator >::data() const", referenced from: std::__1::ostreambuf_iterator > std::__1::__pad_and_output >(std::__1::ostreambuf_iterator >, char const*, char const*, char const*, std::__1::ios_base&, char) in generated-b4252a.o "std::__1::basic_ostream >::sentry::operator bool() const", referenced from: std::__1::basic_ostream >& std::__1::__put_character_sequence >(std::__1::basic_ostream >&, char const*, unsigned long) in generated-b4252a.o "std::__1::basic_ios >::fill() const", referenced from: std::__1::basic_ostream >& std::__1::__put_character_sequence >(std::__1::basic_ostream >&, char const*, unsigned long) in generated-b4252a.o "std::__1::basic_ios >::rdbuf() const", referenced from: std::__1::ostreambuf_iterator >::ostreambuf_iterator(std::__1::basic_ostream >&) in generated-b4252a.o "std::__1::basic_ios >::widen(char) const", referenced from: std::__1::basic_ostream >& std::__1::endl >(std::__1::basic_ostream >&) in generated-b4252a.o "std::__1::basic_string, std::__1::allocator >::basic_string(unsigned long, char)", referenced from: std::__1::ostreambuf_iterator > std::__1::__pad_and_output >(std::__1::ostreambuf_iterator >, char const*, char const*, char const*, std::__1::ios_base&, char) in generated-b4252a.o "std::__1::basic_ios >::setstate(unsigned int)", referenced from: std::__1::basic_ostream >& std::__1::__put_character_sequence >(std::__1::basic_ostream >&, char const*, unsigned long) in generated-b4252a.o ld: symbol(s) not found for architecture x86_64 clang-3.9: error: linker command failed with exit code 1 (use -v to see invocation)
我不认为这是一个名称重整问题。只要你没有碰到名字,你应该没问题。相反,这是一个链接问题。 lli没有链接到任何库中,所以STL符号无法解析。如果你编译和链接模块,你应该没问题...... llc test.ll,clang ++ test.s(或其他编译器)。让我知道这是否有帮助,我会将其添加为答案。 – Tobias
...你是否用clang ++ -S -mit-llvm生成IR?以任何方式编辑文件?你想让它运行吗?或者你想知道你想自己生成一个损坏的名字是如何改名的? – Tobias
@Tobias我使用'clang :: CreateLLVMCodeGen'工厂和'HandleTopLevelDecl'生成了LLVM – sdgfsdh