Dear All,
In my development, a function returns a struct {i8*, i64}, and on the
call site I need to assign the return value to a struct of type {some_struct*, i64}.
One way to do it is to call the mutateType() method of llvm::Value on
the return value of the function call; however, I’m concerned that this mutateType()
method might be too disruptive (it’s discouraged to use it by the documentation).
Since LLVM does not support cast between structs. Is there any way I can safely
“cast” a value of one struct type to another?
Thanks,
- Jie
You can
1. extract individual elements of {i8*, i64},
2. bitcast the first to some_struct*,
3. insert them into a new struct of type {some_struct*, i64}.
You can
1. extract individual elements of {i8*, i64},
2. bitcast the first to some_struct*,
3. insert them into a new struct of type {some_struct*, i64}.
Thanks for the help. I’m thinking the same way. Now I’m stuck with
how to create a struct; I know how to create a llvm::StructType but
I’m not clear of how to create a Value whose type is struct). It seems that
llvm disallowed directly create a Value object; all Values are created from
one of its numerous descendants. Can you give me some guidance here?
Thanks,
- Jie
The "trick" is to start with "undef" (which always exists for any type).
-Krzysztof
Thanks for the help. I’m thinking the same way. Now I’m stuck with how to
create a struct; I know how to create a llvm::StructType but I’m not clear of
how to create a Value whose type is struct). It seems that llvm disallowed
directly create a Value object; all Values are created from one of its
numerous descendants. Can you give me some guidance here?
The “trick” is to start with “undef” (which always exists for any type).
Thanks very much for the direction. This UndefValue method works for me.
For anyone who’s interested in more details, here is the code snippet that
“cast” a struct of type {i8*, i64} to a struct of type {some_struct*, i64}:
// V is a struct of type {i8*, i64}, and RetIRTy is type {some_struct*, i64}.
llvm::UndefValue *newRet = llvm::UndefValue::get(RetIRTy);
llvm::Value *genericPtr = Builder.CreateExtractValue(V, 0);
llvm::Value *ID = Builder.CreateExtractValue(V, 1);
llvm::Value *concretePtr = Builder.CreateBitCast
(genericPtr, castllvm::StructType(RetIRTy)->getElementType(0));
llvm::Value *insertPtr = Builder.CreateInsertValue(newRet, concretePtr, 0);
V = Builder.CreateInsertValue(insertPtr, ID, 1);