How to cast an integer array to an integer pointer? (user question)

I am new to LLVM and couldn't find any llvm-user list, so I am posting my user question here, sorry.

I am trying to create a simple "puts" call accepting the static string, with the code below.
The last line (CallInst::Create) fails with an assert: "Calling a function with a bad signature!"
Because the type of function is void(u8*) and the argument supplied is: getelementptr inbounds [4 x i8]* @0, i32 0
How to convert the pointer to the array to u8* ? I tried BitCastInst but it inserts an explicit bitcast. I don't think this is right.

Yuri

  // assume BasicBlock *BB, Module *M
  // global string
  std::vector<llvm::Constant*> Ivars;
  Ivars.push_back(llvm::ConstantInt::get(Type::getInt8Ty(Context), 0x41));
  Ivars.push_back(llvm::ConstantInt::get(Type::getInt8Ty(Context), 0x42));
  Ivars.push_back(llvm::ConstantInt::get(Type::getInt8Ty(Context), 0x43));
  Ivars.push_back(llvm::ConstantInt::get(Type::getInt8Ty(Context), 0));
  GlobalVariable *GGV = new GlobalVariable(
    *M,
    ArrayType::get(Type::getInt8Ty(Context), 4),
    true, GlobalValue::PrivateLinkage, llvm::ConstantArray::get(ArrayType::get(Type::getInt8Ty(Context), 4), Ivars),
    "g_value_mine", 0, false, 0/*AddrSpace*/);
  // ptr
  GetElementPtrInst *gepi = GetElementPtrInst::CreateInBounds(
    GGV,
    ConstantInt::get(Type::getInt32Ty(Context), 0),
    "zzz",
    BB
    );
  // func call
  Function *PutsF =
    cast<Function>(M->getOrInsertFunction("puts", Type::getVoidTy(Context),
                                          Type::getInt8Ty(Context)->getPointerTo(),
                                          (Type *)0));
  CallInst::Create(PutsF, (Value* const*)&gepi, (Value* const*)(&gepi)+1, "", BB);

I am new to LLVM and couldn't find any llvm-user list, so I am posting
my user question here, sorry.

This is the right mailing list for user questions.

I am trying to create a simple "puts" call accepting the static string,
with the code below.
The last line (CallInst::Create) fails with an assert: "Calling a
function with a bad signature!"
Because the type of function is void(u8*) and the argument supplied is:
getelementptr inbounds [4 x i8]* @0, i32 0
How to convert the pointer to the array to u8* ? I tried BitCastInst but
it inserts an explicit bitcast. I don't think this is right.

I think you're misunderstanding how the getelementptr instruction
works; see http://llvm.org/docs/GetElementPtr.html , and try adding a
call to "gepi->getType()->dump()".

-Eli

GetElementPtrInst *gepi = GetElementPtrInst::CreateInBounds(
GGV,
ConstantInt::get(Type::getInt32Ty(Context), 0),
"zzz",
BB
);

Try using the IRBuilder:

IRBuilder<> irb(BB);
Value* gepi = irb.CreateInBoundsGEP(GGV,
ConstantInt::get(Type::getInt32Ty(Context), 0), "zzz");

Keeping your pointers as Value* makes it easier to deal with using (or
returning) them later.

// func call
CallInst::Create(PutsF, (Value* const*)&gepi, (Value*
const*)(&gepi)+1, "", BB);

Since the return type is void, you can't use Twine, since you only
have one argument, IRBuilder makes it easier for you just to call:

irb.CreateCall(PutsF, gepi);

You can still pass args via pointer/offset, vector or use the helpers
CreateCall[2-4]().

See include/llvm/Support/IRBuilder.h for more info.

cheers,
--renato

Reclaim your digital rights, eliminate DRM, learn more at
http://www.defectivebydesign.org/what_is_drm