llvm2cpp generates incorrcect code in the following case: 1) compile the following function to substitute_bug.bc: #include <stdio.h> extern "C" void NewMarker1() { printf("NewMarker1 \n"); } 2) lvm2cpp -f -gen-function -funcname=makeNewMarker1 -for=NewMarker1 substitute_bug.bc -o substitute_bug.bc.cpp // Generated by llvm2cpp - DO NOT MODIFY! Function* makeNewMarker1(Module *mod) { // Type Definitions std::vector<const Type*>FuncTy_0_args; ParamAttrsList *FuncTy_0_PAL = 0; FunctionType* FuncTy_0 = FunctionType::get( /*Result=*/Type::VoidTy, /*Params=*/FuncTy_0_args, /*isVarArg=*/false, /*ParamAttrs=*/FuncTy_0_PAL); PointerType* PointerTy_1 = PointerType::get(IntegerType::get(8)); ArrayType* ArrayTy_3 = ArrayType::get(IntegerType::get(8), 12); PointerType* PointerTy_2 = PointerType::get(ArrayTy_3); std::vector<const Type*>FuncTy_5_args; FuncTy_5_args.push_back(PointerTy_1); ParamAttrsList *FuncTy_5_PAL = 0; FunctionType* FuncTy_5 = FunctionType::get( /*Result=*/IntegerType::get(32), /*Params=*/FuncTy_5_args, /*isVarArg=*/false, /*ParamAttrs=*/FuncTy_5_PAL); PointerType* PointerTy_4 = PointerType::get(FuncTy_5); // Function Declarations Function* func_puts = new Function( /*Type=*/FuncTy_5, /*Linkage=*/GlobalValue::ExternalLinkage, /*Name=*/"puts", mod); // (external, no body) func_puts->setCallingConv(CallingConv::C); // Global Variable Declarations GlobalVariable* gvar_array__str = new GlobalVariable( /*Type=*/ArrayTy_3, /*isConstant=*/true, /*Linkage=*/GlobalValue::InternalLinkage, /*Initializer=*/0, // has initializer, specified below /*Name=*/".str", mod); // Constant Definitions Constant* const_int32_6 = Constant::getNullValue(IntegerType::get(32)); // Global Variable Definitions gvar_array__str->setInitializer(const_array_7); Function* func_NewMarker1 = new Function( /*Type=*/FuncTy_0, /*Linkage=*/GlobalValue::ExternalLinkage, /*Name=*/"NewMarker1", mod); func_NewMarker1->setCallingConv(CallingConv::C); BasicBlock* label_entry = new BasicBlock("entry",func_NewMarker1,0); BasicBlock* label_return = new BasicBlock("return",func_NewMarker1,0); // Block entry (label_entry) std::vector<Value*> ptr_tmp_indices; ptr_tmp_indices.push_back(const_int32_6); ptr_tmp_indices.push_back(const_int32_6); Instruction* ptr_tmp = new GetElementPtrInst(gvar_array__str, &ptr_tmp_indices[0], 2, "tmp", label_entry); CallInst* int32_tmp1 = new CallInst(func_puts, ptr_tmp, "tmp1", label_entry); int32_tmp1->setCallingConv(CallingConv::C); int32_tmp1->setTailCall(false); new BranchInst(label_return, label_entry); // Block return (label_return) new ReturnInst(label_return); return func_NewMarker1; } The "const_array_7" constant definition is missing from the generated code.
I get different output when using LLVM CVS, but it still fails to produce a stand-alone program. This seems to be because in CppWriter::printFunctionUses, ConstantExprs using GlobalValues aren't added to the "gvs" list, and GlobalValues's initializer aren't added to the "consts" list.
Fixed with this patch: http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20070611/050540.html Note: -gen-function is not supposed to generate a stand alone function. It is, however, supposed to generate something that will recreate everything needed by a single function.