I am trying to create a call to a function foo that receives a function pointer (with signature void bar(void)) as argument. From This post I got the basic Idea to accomplish this.
First I register the Foo function. Bar is actually a function that has been compiled by LLVM so there is no registration neccessary.
FunctionType* BarType = FunctionType::get(Type::getVoidTy(getGlobalContext()), false);
Type* FooType[1];
FooType[0] = static_cast<Type*>(BarType)->getPointerTo();
ArrayRef<Type*> FooTypeARef(FooType, 1);
FunctionType* signature = FunctionType::get(Type::getInt32Ty(getGlobalContext()), FooTypeARef, false);
Function* func = Function::Create(signature, Function::ExternalLinkage, "Foo", TheModule);
LLVM_ExecutionEngine()->addGlobalMapping(func, const_cast<void*>(&Foo));
This is how the actual call is inserted (Case I)
std::vector<Value*> ArgsV_Foo;
Function *FooFun= LLVM_Module()->getFunction("Foo");
Function* BarFun = LLVM_Module()->getFunction("Bar");
ArgsV_Foo.push_back( BarFun );
LLVM_Builder()->CreateCall(FooFun, ArgsV, "calltmp")
However, this aborts inside CreateCall with the reason "Calling a function with a bad signature". I am not sure if the line ArgsV_Foo.push_back( BarFun ) is correct.
A different approach that seems possible to me is to use ExecutionEngine to get a pointer to Bar, but I do not understand how to convert the resulting function pointer to a llvm::Value* (Case II)
std::vector<Value*> ArgsV_Foo;
Function *FooFun= LLVM_Module()->getFunction("Foo");
Function* BarFun = LLVM_Module()->getFunction("Bar");
void* BarFunPtr = LLVM_ExecutionEngine()->getPointerToFunction(BarFun);
Value* val = ??
ArgsV_FEFork.push_back(val);
LLVM_Builder()->CreateCall(FooFun, ArgsV, "calltmp")
Maybe someone has an idea how to accomplish the second case or confirm that the assignment in the first case is correct (and the problem sits elsewhere).
I'm not quite sure what's going on there. Why do you upcast BarType, for example? In any case, an easy way to check it out would be to call ->dump() on all the types involved and check out for yourself what the differences are.
Also, avoid using static_cast on LLVM objects - there are more canonical ways to cast.
BarFunPtr) to an integer.inttoptr. The pointer's type should be a function pointer matching bar's type.ArrayRefsFinally, just FYI, there are easier ways to create ArrayRef instances.... In particular you might be interested in its implicit single-element constructor :-)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With