insert printf into IR

Hi All,
I am trying to insert printf ("%d", v), where v is an integer param, into the IR.
I am doing something wrong because I keep getting segfaults.
Below is my code. Thanks.

vector<const Type *> params;
params.push_back(Type::getInt8PtrTy(M.getContext()));
params.push_back(Type::getInt32Ty(M.getContext()));
FunctionType *fType = FunctionType::get(Type::getInt32Ty(M.getContext()), params, true);
Constant *temp = M.getOrInsertFunction(“printf”,fType);
if(!temp){
errs() << “printf function not in symbol table\n”;
exit(1);
}
Function *f = cast(temp);
f->setCallingConv(CallingConv::C);

Value *intparam = …

Value *strPtr = builder.CreateGlobalStringPtr(str,"");

builder.CreateCall2(PrintF, strPtr, intparam,“tmp6”);

Hi All,
I am trying to insert printf ("%d", v), where v is an integer param, into
the IR.
I am doing something wrong because I keep getting segfaults.
Below is my code. Thanks.

vector<const Type *> params;
params.push_back(Type::getInt8PtrTy(M.getContext()));
params.push_back(Type::getInt32Ty(M.getContext()));

You don't need the i32 type as an explicit parameter; the 'true'
isVarArg argument to FunctionType::get() below allows the call to
handle the int parameter.

FunctionType *fType =
FunctionType::get(Type::getInt32Ty(M.getContext()), params, true);
Constant *temp = M.getOrInsertFunction("printf",fType);
if(!temp){
errs() << "printf function not in symbol table\n";
exit(1);
}
Function *f = cast<Function>(temp);

Because you were providing a non-standard parameter list above,
getOrInsertFunction() returned a bitcast'ed function, not a "raw"
function (if there was already a declaration/definition of printf()
available)
In general, you can't be sure it returns a Function*.

f->setCallingConv(CallingConv::C);

Also, the C calling convention is the default and if there's an
existing declaration it should already be correct, hopefully.

Value *intparam = ...
Value *strPtr = builder.CreateGlobalStringPtr(str,"");
builder.CreateCall2(PrintF, strPtr, intparam,"tmp6");

If there *were* a need to set the calling convention, you'd also want
to set it on the call. But as I said, the C calling convention is the
default.

If this code produced segfaults instead of producing assertion
failures, that means you compiled without assertions enabled. I
recommend recompiling with assertions enabled, it really helps catch
these kinds of mistakes.

Hi George,

   I am trying to insert printf ("%d", v), where v is an integer param, into the IR.
I am doing something wrong because I keep getting segfaults.

if you are doing development with LLVM then you should build LLVM with
assertions enabled. That way you get understandable failures rather
than obscure segmentation faults.

Function *f = cast<Function>(temp);

If printf was already present in the module but with a different type then
temp will be a bitcast of the existing declaration (the bitcast changing
the type), and this will fail.

Ciao, Duncan.

Hi Duncan,
I replaced cast with dyn_cast and f is not null.

The problem happens to be coming from the CreateGlobalStringPtr.I am getting this error,

dyld: lazy symbol binding failed: Symbol not found: __ZN4llvm13IRBuilderBase18CreateGlobalStringEPKcRKNS_5TwineE
Referenced from: /Users/georgebaah/llvm_dir/llvm-2.8/Debug+Asserts/lib/LLVMMyTest.dylib
Expected in: flat namespace

dyld: Symbol not found: __ZN4llvm13IRBuilderBase18CreateGlobalStringEPKcRKNS_5TwineE
Referenced from: /Users/georgebaah/llvm_dir/llvm-2.8/Debug+Asserts/lib/LLVMMyTest.dylib
Expected in: flat namespace

Thanks.

George