通过LLVM C接口创建和引用字符串文字
我试图通过LLVM C API创建一个字符串文本,并获取指向其第一个成员的C风格指针通过LLVM C接口创建和引用字符串文字,llvm,Llvm,我试图通过LLVM C API创建一个字符串文本,并获取指向其第一个成员的C风格指针LLVMBuildGlobalStringPtr很好地实现了这一点,但我无法使用它,因为我的源字符串可能包含null 我似乎找不到关于如何创建初始化的、未命名的常量全局字符串的文档 我尝试使用LLVMConstString创建字符串,并llvmconstnttoptr获取其地址(然后使用GetElementPointer转换为i8*)。我可以让LLVM来编译它,但是生成的对象文件不包含字符串,代码返回一个看似随机
LLVMBuildGlobalStringPtr
很好地实现了这一点,但我无法使用它,因为我的源字符串可能包含null
我似乎找不到关于如何创建初始化的、未命名的常量全局字符串的文档
我尝试使用
LLVMConstString
创建字符串,并llvmconstnttoptr
获取其地址(然后使用GetElementPointer转换为i8*
)。我可以让LLVM来编译它,但是生成的对象文件不包含字符串,代码返回一个看似随机的指针。我找到了答案。下面的代码段似乎可以做到这一点:
LLVMValueRef defineStringLiteral( const char *sourceString, size_t size ) {
LLVMTypeRef strType = LLVMArrayType( LLVMInt8Type(), size );
LLVMValueRef str = LLVMAddGlobal(module->getLLVMModule(), strType, "");
LLVMSetInitializer(str, LLVMConstString( sourceString, size, true ));
LLVMSetGlobalConstant(str, true);
LLVMSetLinkage(str, LLVMPrivateLinkage);
LLVMSetUnnamedAddress(str, LLVMGlobalUnnamedAddr);
LLVMSetAlignment(str, 1);
LLVMValueRef zeroIndex = LLVMConstInt( LLVMInt64Type(), 0, true );
LLVMValueRef indexes[2] = { zeroIndex, zeroIndex };
LLVMValueRef gep = LLVMBuildInBoundsGEP2(builder, strType, str, indexes, 2, "");
return gep;
}
所以基本上你所做的就是用C语言创建一个
char
数组,然后用strcpy
复制const char*
,我不确定我是否理解你的问题。列出的操作发生在编译时。没有字符串的运行时复制。正如您所期望的,它被放置在rodata
中。这不是一个问题,而是一个观察结果。那么,观察结果是错误的。LLVM的初始值设定项不是strcpy(甚至也不是memcpy)。LLVM中的所有这些修改都是在代码生成时追溯发生的,这就是我说等效的原因。使用const char*
初始化i8
数组类似于将strcpy放入相同类型的数组中。仅仅因为后者发生在运行时并不意味着它们不相同。