I want to translate a c callback function to an llvm function using the c++ api. My example c++ function is like below.
extern "C" void bindMe(int(*compare)(const int a))
{
llvm::LLVMContext& context = llvm::getGlobalContext();
llvm::Module *module = new llvm::Module("top", context);
llvm::IRBuilder<> builder(context);
//I want to create the corresponding llvm function here which is called compareLLVM
llvm::BasicBlock *entry = llvm::BasicBlock::Create(context, "entrypoint", compareLLVM);
builder.SetInsertPoint(entry);
module->dump();
}
Basically I want to translate the argument of bindMe function, which is a c callback function, to a corresponding llvm function. Is something like this possible using the API ?
I will really appreciate any ideas.
Thank you
compare
is a pointer to where the compiled code of a function resides. There's no source code there - in fact, it might even not have been compiled from C - so there's not much LLVM can do with it, and you cannot convert it to an LLVM Function
object.
What you can do is insert a call to that function: create an LLVM Value
from that compare
pointer, cast it to the appropriate type, then create a call instruction with that casted pointer as the function. Inserting such a call with the API will look something like:
Type* longType = Type::getInt64Ty(context);
Type* intType = Type::getInt32Ty(context);
Type* funcType = FunctionType::get(intType, intType, false);
// Insert the 'compare' value:
Constant* ptrInt = ConstantInt::get(longType, (long long)compare);
// Convert it to the correct type:
Value* ptr = ConstantExpr::getIntToPtr(ptrInt, funcType->getPointerTo());
// Insert function call, assuming 'num' is an int32-typed
// value you have already created:
CallInst* call = builder.CreateCall(ptr, num);