通过LLVM C接口创建和引用字符串文字

通过LLVM C接口创建和引用字符串文字,llvm,Llvm,我试图通过LLVM C API创建一个字符串文本,并获取指向其第一个成员的C风格指针LLVMBuildGlobalStringPtr很好地实现了这一点,但我无法使用它,因为我的源字符串可能包含null 我似乎找不到关于如何创建初始化的、未命名的常量全局字符串的文档 我尝试使用LLVMConstString创建字符串,并llvmconstnttoptr获取其地址(然后使用GetElementPointer转换为i8*)。我可以让LLVM来编译它,但是生成的对象文件不包含字符串,代码返回一个看似随机

我试图通过LLVM C API创建一个字符串文本,并获取指向其第一个成员的C风格指针
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放入相同类型的数组中。仅仅因为后者发生在运行时并不意味着它们不相同。