所以我创建了一个结构类型与此:如何获取LLVM中结构成员的值?
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)
,我想知道如何在结构内访问的成员。
我使用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");
感谢您的任何反馈!
编辑:
好了,所以的llvm::Value* data
类型是将其从堆栈上的指针加载的%a_struct
。从文档看来,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(...)
的指针是llvm::AllocaInst*
,该堆栈新分配到堆栈并且包含复制到其中的值llvm::Value* data
(类型%a_struct
)。
的IR所产生的呼叫irbuilder.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
}
而且应该有更好的方式来访问的%a_var
成员,而无需复制它(同时仍在语言中支持表达式如a_struct_var1.member + a_struct_var2.member
)。
当你说你已经使用getelementptr没有运气尝试过,你是什么意思?生成的LLVM IR看起来像什么? –
@FrankC。当调用irbuilder.CreateInBoundsGEP(...)时,断言失败并打印此消息:“Expression:isa(Val)&&”cast ()argument of incompatible type!“'。我尝试将llvm :: Value *复制到堆栈中的一个变量上,但是接着另一个断言失败:'Expression:getOperand(0) - > getType()== cast (getOperand(1) - > getType()) - > getElementType()&&“Ptr必须是一个指向Val类型的指针!'我在考虑对'llvm :: Value * data =/* expression * /'做错了什么,所以我我会研究它的类型数据。 –