4 #include "codegen/CodeGen.h"
5 #include "codegen/Mangling.h"
6 #include "tir/IRBuilder.h"
7 #include "tir/Instructions.h"
9 #include "utils/Utils.h"
13 void CodeGenerator::emitFunctionDecl(ast::MethodDecl
const* decl) {
15 if(decl->modifiers().isAbstract())
return;
17 auto astRetTy = decl->returnTy().type;
18 tir::
Type* tirRetTy = tir::
Type::getVoidTy(ctx);
19 if(astRetTy) tirRetTy = emitType(astRetTy);
20 std::vector<tir::Type*> paramTys;
21 std::vector<std::string_view> paramNames;
23 if(!decl->modifiers().isStatic()) {
24 paramTys.push_back(tir::Type::getPointerTy(ctx));
25 paramNames.push_back(
"this");
28 for(
auto* param : decl->parameters()) {
29 paramTys.push_back(emitType(param->type()));
30 paramNames.push_back(param->name());
33 auto* funcTy = tir::FunctionType::get(ctx, tirRetTy, paramTys);
37 tir::Function* func =
nullptr;
38 if(decl->modifiers().isNative()) {
39 std::ostringstream ss;
41 func = cu.CreateFunction(funcTy, ss.str());
42 func->setExternalLinkage();
45 m.MangleFunctionName(decl);
46 func = cu.CreateFunction(funcTy, m.getMangledName());
48 if(decl
->name() ==
"main") {
49 func->setExternalLinkage();
53 assert(func &&
"Function already exists");
54 for(
auto arg : func->args()) {
55 arg->setName(paramNames[arg->index()]);
59 void CodeGenerator::emitFunction(ast::MethodDecl
const* decl) {
61 if(decl->modifiers().isNative())
return;
62 assert(decl->body() &&
"Function should not be abstract here");
64 auto func = cast<tir::Function>(gvMap[decl]);
68 auto entry = builder.createBasicBlock(func);
69 builder.setInsertPoint(entry->begin());
70 for(
auto* local : decl->decls()) {
71 auto* typedLocal = cast<ast::TypedDecl>(local);
72 auto* localTy = emitType(typedLocal->type());
73 auto* val = func->createAlloca(localTy);
74 val->setName(typedLocal->name());
75 valueMap[local] = cast<tir::AllocaInst>(val);
77 emitStmt(decl->body());
79 if(builder.currentBlock()) {
80 auto term = builder.currentBlock()->terminator();
81 if(!term || !term->isTerminator()) {
82 builder.createReturnInstr();