I want to create a external function call and this function is getting arguments as int
and const char*
(ESPECIALLY BASICBLOCK NAME, not custom string)(or std::string
could be fine).
But I have no idea about setting the function argument as const char*
or std::string
. The only thing that I realized is string is treated as Int8PtrTy
in LLVM.
LLVMContext &ctx = F->getContext();
Constant *countfunc = F->getParent()->getOrInsertFunction(
"bbexectr", Type::getVoidTy(ctx), Type::getInt32Ty(ctx), Type::getInt8PtrTy(ctx));
for (Function::iterator ibb = ifn->begin(); ibb != ifn->end(); ++ibb)
{
BasicBlock *B = &*ibb;
IRBuilder<> builder(B);
builder.SetInsertPoint(B->getTerminator());
std::string str = B->getName().str();
const char* strVal = str.c_str();
Value *args[] = {builder.getInt32(index), builder.getInt8PtrTy(*strVal)};
builder.CreateCall(countfunc, args);
I tried upper code but it gave me an error message like below.
error: cannot convert ‘llvm::PointerType*’ to ‘llvm::Value*’ in initialization
Value *args[] = {builder.getInt32(index), builder.getInt8PtrTy(*strVal)};
Is there any way to solve the error, or is there any better method to setting the function argument as basicblock name???
Types and Values are different in LLVM. llvm::Type represent types and llvm::Value represents values. Since Type and Value belong to different class hierarchies an llvm::Value *args[] cannot be initialized with subclasses of llvm::Type hierarchy. What you might want to do instead is changing
Value *args[] = {builder.getInt32(index), builder.getInt8PtrTy(*strVal)};
To
llvm::Value *strVal = builder.CreateGlobalStringPtr(str.c_str());
llvm::Value *args[] = {builder.getInt32(index), strVal};
CreateGlobalStringPtr() will create a global string and return a pointer of type Int8PtrTy.