Reputation: 1116
Suppose I have a StructType
ingredient, which is defined as:
// volume[0] = quantity
// volume[1] = unit (e.g. mL, L, etc.)
Type *volume[2] = {Type::getFloatTy(this->context), Type::getInt8Ty(this->context)};
ArrayRef<Type*> refs(volume);
this->volumeType = StructType::create(this->context, refs, "volume", true);
Type *types[2] = {this->volumeType, ArrayType::get(Type::getInt8Ty(this->context), 100)};
refs = ArrayRef<Type*>(types);
this->ingredientType = StructType::create(this->context, refs, "ingredient", true);
=========================
Suppose I have the following:
Ingredient x();
x.volume.unit = 0; // where 0 denotes 'mL'
x.volume.quantity = 100.0;
I don't fully understand how to set the x.volume.unit
value using the LLVM C++ API.
I was reading how the GetElementPtrInstr
works from here and here. And essentially, 1 states that I can reference the value(s) I want to assign in a StructType
by the ArrayRef
IdxList. Where IdxList[0][n]
is the nth element in the struct. However, what I wasn't sure, and can't get working, is how to set the values in the nested volume
struct that I have.
I've tried sending a multi-dimensional ArrayRef
but with no luck. So I'm sort of stuck with respect to setting a value inside the volume
StructType which is nested inside the ingredient
StructType.
Upvotes: 0
Views: 391
Reputation: 9685
Nesting is just an additional argument to getelementptr.
If you access x.volume using getelementptr indices 0, n, then x.volume.unit is acessible using indices 0,n,0 and x.volume.quantity is 0,n,1.
As Ismail Badawi says, you can ask Clang to show you how to do it. If a GEP doesn't do what you want (or any other Instruction, for that matter), you may find it educational to call x->getType()->dump()
to dump a description of the type you get to stderr.
I suggest that you try setting the unit using 0,0,0, and if it does not work, dump the type of 0,0,0 and see if you recognize it. You give GEP a pointer, the first zero gives you a struct (x
), the second gives you another struct (it steps into .volume
), the third probably a float (it steps into .unit
) and finally GEP implicitly takes the address of that, so the return type of the GEP is a pointer to float. You can give that pointer to a StoreInst to write a float into the struct.
Upvotes: 2