| 276 | } |
| 277 | |
| 278 | Function *codegenFunDef(codegen_t &cg, ast_t *ast) { |
| 279 | assert(ast->type == AST_FUNDEF); |
| 280 | cg.variables.clear(); |
| 281 | |
| 282 | Function *func = codegenProto(cg, ast); |
| 283 | if (!func) |
| 284 | return (Function *)errorVal("codegenFunDef: codegenProto() failed\n"); |
| 285 | |
| 286 | ast_t *astbody = ast->as_fundef.body; |
| 287 | if (!astbody) |
| 288 | return func; // prototype |
| 289 | |
| 290 | BasicBlock *bb = BasicBlock::Create(getGlobalContext(), "entry", func); |
| 291 | cg.ir_builder.SetInsertPoint(bb); |
| 292 | |
| 293 | Value *bodyval = codegen(cg, astbody); |
| 294 | if (! bodyval) { |
| 295 | func->eraseFromParent(); |
| 296 | return (Function *)errorVal("codegenFunDef: codegen(body) failed\n"); |
| 297 | } |
| 298 | |
| 299 | cg.ir_builder.CreateRet(bodyval); |
| 300 | verifyFunction(*func); |
| 301 | |
| 302 | if (cg.fpm) |
| 303 | cg.fpm->run(*func); |
| 304 | |
| 305 | return func; |
| 306 | } |
| 307 | |
| 308 | inline Value *codegenNum(codegen_t &cg, ast_t *ast) { |
| 309 | assert(ast->type == AST_NUM); |