-
Notifications
You must be signed in to change notification settings - Fork 103
Expand file tree
/
Copy pathCGModule.cpp
More file actions
102 lines (93 loc) · 3.07 KB
/
CGModule.cpp
File metadata and controls
102 lines (93 loc) · 3.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#include "tinylang/CodeGen/CGModule.h"
#include "tinylang/CodeGen/CGProcedure.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/CommandLine.h"
using namespace tinylang;
static llvm::cl::opt<bool>
Debug("g", llvm::cl::desc("Generate debug information"),
llvm::cl::init(false));
CGModule::CGModule(ASTContext &ASTCtx, llvm::Module *M)
: ASTCtx(ASTCtx), M(M) {
initialize();
}
void CGModule::initialize() {
VoidTy = llvm::Type::getVoidTy(getLLVMCtx());
Int1Ty = llvm::Type::getInt1Ty(getLLVMCtx());
Int32Ty = llvm::Type::getInt32Ty(getLLVMCtx());
Int64Ty = llvm::Type::getInt64Ty(getLLVMCtx());
Int32Zero =
llvm::ConstantInt::get(Int32Ty, 0, /*isSigned*/ true);
}
llvm::Type *CGModule::convertType(TypeDeclaration *Ty) {
if (llvm::Type *T = TypeCache[Ty])
return T;
if (llvm::isa<PervasiveTypeDeclaration>(Ty)) {
if (Ty->getName() == "INTEGER")
return Int64Ty;
if (Ty->getName() == "BOOLEAN")
return Int1Ty;
} else if (auto *AliasTy =
llvm::dyn_cast<AliasTypeDeclaration>(Ty)) {
llvm::Type *T = convertType(AliasTy->getType());
return TypeCache[Ty] = T;
} else if (auto *ArrayTy =
llvm::dyn_cast<ArrayTypeDeclaration>(Ty)) {
llvm::Type *Component = convertType(ArrayTy->getType());
Expr *Nums = ArrayTy->getNums();
uint64_t NumElements = 5; // TODO Eval Nums
if(auto *intergerExpr = llvm::dyn_cast<IntegerLiteral>(Nums)){
NumElements = intergerExpr->getValue().getExtValue();
}
llvm::Type *T =
llvm::ArrayType::get(Component, NumElements);
return TypeCache[Ty] = T;
} else if (auto *RecordTy =
llvm ::dyn_cast<RecordTypeDeclaration>(
Ty)) {
llvm::SmallVector<llvm::Type *, 4> Elements;
for (const auto &F : RecordTy->getFields()) {
Elements.push_back(convertType(F.getType()));
}
llvm::Type *T = llvm::StructType::create(
Elements, RecordTy->getName(), false);
return TypeCache[Ty] = T;
}
llvm::report_fatal_error("Unsupported type");
}
std::string CGModule::mangleName(Decl *D) {
std::string Mangled;
llvm::SmallString<16> Tmp;
while (D) {
llvm::StringRef Name = D->getName();
Tmp.clear();
Tmp.append(llvm::itostr(Name.size()));
Tmp.append(Name);
Mangled.insert(0, Tmp.c_str());
D = D->getEnclosingDecl();
}
Mangled.insert(0, "_t");
return Mangled;
}
llvm::GlobalObject *CGModule::getGlobal(Decl *D) {
return Globals[D];
}
void CGModule::run(ModuleDeclaration *Mod) {
this->Mod = Mod;
for (auto *Decl : Mod->getDecls()) {
if (auto *Var =
llvm::dyn_cast<VariableDeclaration>(Decl)) {
// Create global variables
llvm::GlobalVariable *V = new llvm::GlobalVariable(
*M, convertType(Var->getType()),
/*isConstant=*/false,
llvm::GlobalValue::PrivateLinkage, nullptr,
mangleName(Var));
Globals[Var] = V;
} else if (auto *Proc =
llvm::dyn_cast<ProcedureDeclaration>(
Decl)) {
CGProcedure CGP(*this);
CGP.run(Proc);
}
}
}