int main() { llvm::LLVMContext &context = llvm::getGlobalContext(); llvm::Module *module = new llvm::Module("hello_world", context); llvm::IRBuilder<> builder(context); // define main() as void llvm::FunctionType *funcType = llvm::FunctionType::get(builder.getVoidTy(), false); llvm::Function *mainFunc = llvm::Function::Create(funcType, llvm::Function::ExternalLinkage, "main", module); llvm::BasicBlock *entry = llvm::BasicBlock::Create(context, "entrypoint", mainFunc); builder.SetInsertPoint(entry); // define the 'hello world' string constant llvm::Value *helloWorld = builder.CreateGlobalStringPtr("Hello world!"); // define the args to puts() std::vector<llvm::Type*> putsArgs; putsArgs.push_back(builder.getInt8Ty()->getPointerTo()); llvm::ArrayRef<llvm::Type*> argsRef(putsArgs); llvm::FunctionType *putsType = llvm::FunctionType::get(builder.getInt32Ty(), // return type argsRef, // argument vector false); // no variable number of args llvm::Constant *putsFunc = module->getOrInsertFunction("puts", putsType); // call puts(hello_world) builder.CreateCall(putsFunc, helloWorld); builder.CreateRetVoid(); module->dump(); }
bool CodeGen::wrapTopLevelBlockInMain(BlockAST *ast) { // add main to scope addScope("main"); vector<unique_ptr<ASTNode> > * body = ast->body.get(); // generate void main() llvm::FunctionType *voidType = llvm::FunctionType::get(Builder.getVoidTy(), false); llvm::Function *mainFunc = llvm::Function::Create(voidType, llvm::Function::ExternalLinkage, "main", module.get()); // basic block for the top level block llvm::BasicBlock *MainBlock = llvm::BasicBlock::Create(context, "entry", mainFunc); Builder.SetInsertPoint(MainBlock); llvm::Value * lastExpr; for (auto it = body->begin() ; it != body->end(); ++it) { ASTNode * node = it->get(); if (auto x = dynamic_cast<ValueAST*>(node)) { auto code = generateCodeValue(x); if (!code) return false; } else if (auto x = dynamic_cast<DefAST*>(node)) { generateCodeDef(x); Builder.SetInsertPoint(MainBlock); } else if (auto x = dynamic_cast<NumberExprAST*>(node)) { auto code = generateCodeNumber(x); if (!code) return false; lastExpr = code; } else if (auto x = dynamic_cast<BinaryExprAST*>(node)) { auto code = generateCodeBinOp(x); if (!code) return false; lastExpr = code; } else if (auto x = dynamic_cast<CallAST*>(node)) { auto code = generateCodeCall(x); if (!code) return false; lastExpr = code; } else { error = "can't handle ast"; return false; } } llvm::Value *fmt = Builder.CreateGlobalStringPtr("%lg\n"); vector<llvm::Type *> putsArgs; putsArgs.push_back(Builder.getInt8Ty()->getPointerTo()); llvm::ArrayRef<llvm::Type*> argsRef(putsArgs); llvm::FunctionType *putsType = llvm::FunctionType::get(Builder.getInt32Ty(), argsRef, true); llvm::Constant *putsFunc = module->getOrInsertFunction("printf", putsType); vector<llvm::Value *> CallArgs; CallArgs.push_back(fmt); CallArgs.push_back(lastExpr); Builder.CreateCall(putsFunc, CallArgs); Builder.CreateRetVoid(); string verifyS; llvm::raw_string_ostream verifyE(verifyS); if (verifyFunction(*mainFunc, &verifyE)) { mainFunc->eraseFromParent(); error = "something wrong with auto-generated main function: " + verifyS; return false; } // remove the main scope removeScope(); return true; }