LLVM从结构值中提取i8*
LLVM extract i8* out of structure value
我正在编写一个使用LLVM作为后端的编译器,我已经编写了前端(解析器等),现在我已经走到了十字路口。
我有一个结构(%Primitive),它包含一个字段,一个i8*值,一个指向字符数组的指针。
%Primitive = type { i8* }
在编译器中,Primitive
的实例在堆栈上传递。我正试图使用puts
函数将这个字符数组写入标准输出,但它并不像我希望的那样工作。
declare i32 @puts(i8*) ; Declare the libc function 'puts'
define void @WritePrimitive(%Primitive) {
entry:
%1 = extractvalue %Primitive %0, 0 ; Extract the character array from the primitive.
%2 = call i32 @puts(i8* %1) ; Write it
ret void
}
当我尝试运行代码(使用ExecutionEngine或LLVM解释器程序lli
)时,我会得到同样的错误;分割错误。
错误在于传递给puts
的地址在某种程度上是数组中第一个字符的ASCII字符代码。似乎传递的地址不是指向8位字符数组的指针,而是一个8位宽的指针,等于取消引用的字符串。
例如,如果我用一个基元调用@WritePrimitive
,其中i8*成员指向字符串"hello"
,则调用puts
,字符串地址为0x68
。
有什么想法吗?
感谢
编辑:你是对的,我错误地初始化了我的Primitive
,我的新初始化函数是:
llvm::Value* PrimitiveHelper::getConstantPrimitive(const std::string& str, llvm::BasicBlock* bb)
{
ConstantInt* int0 = ConstantInt::get(Type::getInt32Ty(getGlobalContext()), 0);
Constant* strConstant = ConstantDataArray::getString(getGlobalContext(), str, true);
GlobalVariable* global = new GlobalVariable(module,
strConstant->getType(),
true, // Constant
GlobalValue::ExternalLinkage,
strConstant,
"str");
Value* allocated = new AllocaInst(m_primitiveType, "allocated", bb);
LoadInst* onStack1 = new LoadInst(allocated, "onStack1", bb);
GetElementPtrInst* ptr = GetElementPtrInst::Create(global, std::vector<Value*>(2,int0), "", bb);
InsertValueInst* onStack2 = InsertValueInst::Create(onStack1, ptr, std::vector<unsigned>(1, 0), "", bb);
return onStack2;
}
我错过了,谢谢!
上面粘贴的代码没有任何问题;我只是自己试了一下,效果很好。我猜问题是您没有正确初始化指针,或者没有将其正确设置到结构中。
我使用的完整代码是:
@str = private unnamed_addr constant [13 x i8] c"hello world A 0"
; Your code
%Primitive = type { i8* }
declare i32 @puts(i8*) ; Declare the libc function 'puts'
define void @WritePrimitive(%Primitive) {
entry:
%1 = extractvalue %Primitive %0, 0 ; Extract the character array from the primitive.
%2 = call i32 @puts(i8* %1) ; Write it
ret void
}
; /Your code
define void @main() {
%allocated = alloca %Primitive
%onstack1 = load %Primitive* %allocated
%onstack2 = insertvalue %Primitive %onstack1, i8* getelementptr ([13 x i8]* @str, i64 0, i64 0), 0
call void @WritePrimitive(%Primitive %onstack2)
ret void
}
相关文章:
- 从包含m行的文件中提取n行,必要时(惰性地)重复该文件
- 如何从 std::atomic 中提取指针 T<T>?
- 为什么istream不支持右值提取
- 如何设置一个范围来提取我想要获得的信息
- 视觉工作室项目.提取源文件夹名称
- C++17 - 使用自定义分配器的节点提取/重新插入 - 适用于 clang++/libc++,但不适用于 libstd
- 从字符串中提取整数并形成一个数组
- C ++中的StringStream有助于使用向量从字符串中提取逗号分隔的整数,而不是空格分隔的整数,为什么?
- asn1c 不会从 asn.1 模块中提取八位字节字符串的默认值
- 从 std::vector<无符号字符>切片中提取 int?
- 在C++中使用重载提取运算符时出现问题
- 在 Qt(C++) 中使用 QProcess 解压缩 - 提取目录问题
- C++(.cpp文件和.h文件)拆分代码并添加一个函数,提取 - 这很容易吗?
- 无法从 std::string 中提取C++ Unicode 符号
- 如何从也包含C++字母的文本文件中提取某些数字?
- 如何从适合一定范围的数字中提取数字?
- C++从通用引用中提取实际类型
- 从运行服务的应用程序代码中提取窗口句柄
- 如何在字符串中找到字符,然后在C++中提取其余的字符串
- LLVM从结构值中提取i8*