Search code examples
c++llvmllvm-clangllvm-c++-api

LLVM : How to set a CreateCall argument to BasicBlock name?


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???


Solution

  • 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.