Таким образом, я создал тип структуры с этим:Как получить значение члена структуры в 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
), скопированное в нее.
ИК генерируется непосредственно перед вызовом 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 () аргумент несовместимого типа! "'. Я попытался скопировать llvm :: Value * в переменную в стеке, но затем не выполняется другое утверждение: 'Expression: getOperand (0) -> getType() == cast (getOperand (1) -> getType()) -> getElementType() && "Ptr должен быть указателем на тип Val!". Я думаю, что я делаю что-то не так с выражением 'llvm :: Value * data =/* * /', поэтому я «Посмотрим на данные типа для него. –