[LLVMdev] insert printf into IR

Frits van Bommel fvbommel at gmail.com
Thu Mar 31 23:35:23 PDT 2011


On Fri, Apr 1, 2011 at 7:46 AM, George Baah <georgebaah at gmail.com> wrote:
> 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.




More information about the llvm-dev mailing list