Calling a function with a pointer to a global char array as argument

Hello;

Thanks to Eli for the pointer to the ConstantDataArray::getString() fucntion. Now I am trying to declare a global char array with the content “hi” and call a function “print” (which takes a char pointer and return an insteger.

I am doing the following in the code -

Function Creation:

PointerType* array = PointerType::get(IntegerType::getInt8Ty(getGlobalContext())
/CI->getPointerOperand()->getType()/, 0);
printFunc = M.getOrInsertFunction(“print”, IntegerType::getInt32Ty(getGlobalContext()), array, NULL);

Global Declaration:

Constant *fname = ConstantDataArray::getString(getGlobalContext(),“hi”, true);
Value *FBloc;
FBloc = new GlobalVariable(M,
fname->getType(),
true,
GlobalValue::InternalLinkage,
fname,
“fBloc”);

Function Call With the Global:

std::vector<Constant*> const_ptr_7_indices;
ConstantInt* const_int32_8 = ConstantInt::get(getGlobalContext(),
APInt(32, StringRef(“0”), 10));
const_ptr_7_indices.push_back(const_int32_8);
const_ptr_7_indices.push_back(const_int32_8);
Constant* const_ptr_7 = ConstantExpr::getGetElementPtr(fname, const_ptr_7_indices);
CallInst* call_print1 = CallInst::Create(func_print, const_ptr_7, “”);
F->getInstList().insert((Instruction*)CI, call_print1); //insert the call instruction

But getting the error on the ConstantExpr::getGetElementPtr() function.

opt: /home/arnie/llvm-clang/llvm/include/llvm/Support/Casting.h:194: typename llvm::cast_retty<To, From>::ret_type llvm::cast(const Y&) [with X = llvm::CompositeType, Y = llvm::Type*, typename llvm::cast_retty<To, From>::ret_type = llvm::CompositeType*]: Assertion `isa(Val) && “cast() argument of incompatible type!”’ failed.

What might I be doing wrong?

Thanks a lot;

Hi Arnamoy,

Thanks to Eli for the pointer to the ConstantDataArray::getString() fucntion.
  Now I am trying to declare a global char array with the content "hi" and call
a function "print" (which takes a char pointer and return an insteger.

I am doing the following in the code -
Function Creation:

PointerType* array = PointerType::get(IntegerType::getInt8Ty(getGlobalContext())
/*CI->getPointerOperand()->getType()*/, 0);

you could use getInt8PtrTy.

printFunc = M.getOrInsertFunction("print",
IntegerType::getInt32Ty(getGlobalContext()), array, NULL);
Global Declaration:

Constant *fname = ConstantDataArray::getString(getGlobalContext(),"hi", true);
Value *FBloc;
FBloc = new GlobalVariable(M,
                                        fname->getType(),
                        true,
                        GlobalValue::InternalLinkage,
                        fname,
                        "fBloc");
Function Call With the Global:

std::vector<Constant*> const_ptr_7_indices;
ConstantInt* const_int32_8 = ConstantInt::get(getGlobalContext(),
APInt(32, StringRef("0"), 10));

This is a silly way of getting zero. You can use
   Constant::getNullValue(Type::getInt32Ty(getGlobalContext()));
or
   ConstantInt::get(Type::getInt32Ty(getGlobalContext()), 0);
but I suggest you create an IRBuilder and do
   Builder.getInt32(0);
and also use the builder for the rest of your construction.

const_ptr_7_indices.push_back(const_int32_8);
Constant* const_ptr_7 = ConstantExpr::getGetElementPtr(fname,

Should be FBloc not fname.

  const_ptr_7_indices);

                                CallInst* call_print1 =
CallInst::Create(func_print, const_ptr_7, "");

Use the IRBuilder to create the call and insert it.

F->getInstList().insert((Instruction*)CI, call_print1); //insert the call
instruction

This is a bad way to insert an instruction. Did you create a basic block to
hold the instruction (you need to)? If so, you can just pass that when you
create the instruction, and the instruction will be added to the end of it.
Better is to pass the basic block to an IRBuilder which will automatically
insert everything you create into that block.

You will also need to create a ReturnInst to finish off the basic block.

Ciao, Duncan.