所以我用这个创建了一个结构类型:
llvm::StructType* llvm_struct = llvm::StructType::create(llvm_context, struct_name);
std::vector<llvm::Type*> members;
for(size_t j = 0; j != struct_data.members.size(); j++){
llvm::Type* member_type = /*get member type*/;
members.push_back(member_type);
}
llvm_struct->setBody(members)
Run Code Online (Sandbox Code Playgroud)
我想知道如何访问结构中的成员。
到目前为止,我已经尝试使用 getelementptr 没有运气:
llvm::Value* member_index = llvm::ConstantInt::get(llvm_context, llvm::APInt(32, /*structure member index*/, true));
llvm::Value* indices[2] = {llvm::ConstantInt::get(member_index->getType(), 0), member_index};
llvm::Value* data = /*expression value*/;
return irbuilder.CreateInBoundsGEP(data, llvm::ArrayRef<llvm::Value*>(indices, 2), "membtmp");
Run Code Online (Sandbox Code Playgroud)
感谢您的任何反馈!
编辑:
好的,所以类型llvm::Value* data是%a_struct从堆栈上的指针加载的 a 。从文档看来,irbuilder.CreateInBoundsGEP(llvm::Value*, llvm::ArrayRef<llvm::Value*>, llvm::Twine)要求第一个参数是指向结构的指针,而不是结构本身的值。
将结构体的值复制到堆栈上的变量中时,会抛出此错误:Expression: getOperand(0)->getType() == cast<PointerType>(getOperand(1)->getType())->getElementType(????) && "Ptr must be a pointer to Val type!"。irbuidler.CreateInBoundsGEP(...)抛出此错误时粘贴到的指针是 an llvm::AllocaInst*,它是在堆栈上新分配的,并包含复制到其中的llvm::Value* data(type of %a_struct)的值。
在调用之前生成的 IRirbuilder.CreateInBoundsGEP(...)将值复制到堆栈上的变量中:
define i32 @main() {
entry:
%calltmp = call %a_struct @new_a_struct()
%a_var = alloca %a_struct
store %a_struct %calltmp, %a_struct* %a_var
%a_var1 = load %a_struct, %a_struct* %a_var
%memballoctmp = alloca %a_struct
store %a_struct %a_var1, %a_struct* %memballoctmp
}
Run Code Online (Sandbox Code Playgroud)
此外,应该有一种更好的方法来访问成员%a_var而不复制它(同时仍然支持a_struct_var1.member + a_struct_var2.member语言中的表达式)。
我已经找到了解决方案。我认为我错误地传递了索引或者其他什么。
注意:我还没有对具有不同数据类型的成员进行测试,但它似乎有效
llvm::Value* member_index = llvm::ConstantInt::get(llvm_context, llvm::APInt(32, index /*The index of the member*/, true));
llvm::Value* data = /*A structure value*/;
llvm::AllocaInst* alloc = irbuilder.CreateAlloca(struct_type, 0, "alloctmp");
irbuilder.CreateStore(data, alloc);
std::vector<llvm::Value*> indices(2);
indices[0] = llvm::ConstantInt::get(llvm_context, llvm::APInt(32, 0, true));
indices[1] = member_index;
llvm::Value* member_ptr = irbuilder.CreateGEP(struct_type, alloc, indices, "memberptr");
llvm::Value* loaded_member = irbuilder.CreateLoad(member_ptr, "loadtmp");
Run Code Online (Sandbox Code Playgroud)