所以我創建了一個結構類型與此:如何獲取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 * /'做錯了什麼,所以我我會研究它的類型數據。 –