lilott8
lilott8

Reputation: 1116

Setting the value of a StructType's StructType

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

Answers (1)

arnt
arnt

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

Related Questions