Joos1W Compiler Framework
All Classes Functions Typedefs Pages
CodeGen.cc
1 #include "codegen/CodeGen.h"
2 
3 #include <utility>
4 
5 #include "ast/AstNode.h"
6 #include "ast/Type.h"
7 #include "tir/Type.h"
8 
9 namespace codegen {
10 
11 using CG = CodeGenerator;
12 
13 CG::CodeGenerator(tir::Context& ctx, tir::CompilationUnit& cu,
14  semantic::NameResolver& nr)
15  : ctx{ctx}, cu{cu}, nr{nr} {
16  arrayType = tir::StructType::get(ctx,
17  {// Length
18  tir::Type::getInt32Ty(ctx),
19  // Pointer
20  tir::Type::getPointerTy(ctx)});
21 }
22 
23 tir::Type* CG::emitType(ast::Type const* type) {
24  using Kind = ast::BuiltInType::Kind;
25  if(isAstTypeReference(type)) {
26  return tir::Type::getPointerTy(ctx);
27  } else if(type->isPrimitive()) {
28  auto ty = cast<ast::BuiltInType>(type);
29  switch(ty->getKind()) {
30  case Kind::Boolean:
31  return tir::Type::getInt1Ty(ctx);
32  case Kind::Char:
33  return tir::Type::getInt16Ty(ctx);
34  case Kind::Short:
35  return tir::Type::getInt16Ty(ctx);
36  case Kind::Int:
37  return tir::Type::getInt32Ty(ctx);
38  case Kind::Byte:
39  return tir::Type::getInt8Ty(ctx);
40  default:
41  std::unreachable();
42  }
43  } else if(type->isArray()) {
44  return arrayType;
45  }
46  std::unreachable();
47 }
48 
49 void CG::run(ast::LinkingUnit const* lu) {
50  for(auto* cu : lu->compliationUnits()) {
51  for(auto* decl : cu->decls()) {
52  if(auto* classDecl = dyn_cast<ast::ClassDecl>(decl)) {
53  emitClassDecl(classDecl);
54  }
55  }
56  }
57  for(auto* cu : lu->compliationUnits()) {
58  for(auto* decl : cu->decls()) {
59  if(auto* classDecl = dyn_cast<ast::ClassDecl>(decl)) {
60  emitClass(classDecl);
61  }
62  }
63  }
64 }
65 
66 tir::Value* CG::emitGetArraySz(tir::Value* ptr) {
67  using namespace tir;
68  auto zero = Constant::CreateInt32(ctx, 0);
69  auto gepSz = builder.createGEPInstr(ptr, arrayType, {zero});
70  gepSz->setName("arr.gep.sz");
71  auto sz = builder.createLoadInstr(Type::getInt32Ty(ctx), gepSz);
72  sz->setName("arr.sz");
73  return sz;
74 }
75 
76 tir::Value* CG::emitGetArrayPtr(tir::Value* ptr) {
77  using namespace tir;
78  auto one = Constant::CreateInt32(ctx, 1);
79  auto gepPtr = builder.createGEPInstr(ptr, arrayType, {one});
80  gepPtr->setName("arr.gep.ptr");
81  auto arrPtr = builder.createLoadInstr(Type::getPointerTy(ctx), gepPtr);
82  arrPtr->setName("arr.ptr");
83  return arrPtr;
84 }
85 
86 void CG::emitSetArraySz(tir::Value* ptr, tir::Value* sz) {
87  using namespace tir;
88  auto zero = Constant::CreateInt32(ctx, 0);
89  auto gepSz = builder.createGEPInstr(ptr, arrayType, {zero});
90  gepSz->setName("arr.gep.sz");
91  builder.createStoreInstr(sz, gepSz);
92 }
93 
94 void CG::emitSetArrayPtr(tir::Value* ptr, tir::Value* arr) {
95  using namespace tir;
96  auto one = Constant::CreateInt32(ctx, 1);
97  auto gepPtr = builder.createGEPInstr(ptr, arrayType, {one});
98  gepPtr->setName("arr.gep.ptr");
99  builder.createStoreInstr(arr, gepPtr);
100 }
101 
102 } // namespace codegen