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<Function>(temp); f->setCallingConv(CallingConv::C); Value *intparam = ... Value *strPtr = builder.CreateGlobalStringPtr(str,""); builder.CreateCall2(PrintF, strPtr, intparam,"tmp6"); -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20110401/cecae798/attachment.html>
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.
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<Function> with dyn_cast<Function> 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 On Fri, Apr 1, 2011 at 2:44 AM, Duncan Sands <baldrick at free.fr> wrote:> 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. > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20110404/1952dc73/attachment.html>