Commit 06def1cd3aa320f39dc285ba6052b336ee2929eb
1 parent
e365a9a8cd
Exists in
master
well
Showing 1 changed file with 1 additions and 0 deletions Inline Diff
ast_decl.cc
View file @
06def1c
/* File: ast_decl.cc | 1 | 1 | /* File: ast_decl.cc | |
* ----------------- | 2 | 2 | * ----------------- | |
* Implementation of Decl node classes. | 3 | 3 | * Implementation of Decl node classes. | |
*/ | 4 | 4 | */ | |
#include "ast_decl.h" | 5 | 5 | #include "ast_decl.h" | |
#include "ast_type.h" | 6 | 6 | #include "ast_type.h" | |
#include "ast_stmt.h" | 7 | 7 | #include "ast_stmt.h" | |
#include "symtable.h" | 8 | 8 | #include "symtable.h" | |
9 | 9 | |||
Decl::Decl(Identifier *n) : Node(*n->GetLocation()) { | 10 | 10 | Decl::Decl(Identifier *n) : Node(*n->GetLocation()) { | |
Assert(n != NULL); | 11 | 11 | Assert(n != NULL); | |
(id=n)->SetParent(this); | 12 | 12 | (id=n)->SetParent(this); | |
} | 13 | 13 | } | |
14 | 14 | |||
VarDecl::VarDecl(Identifier *n, Type *t, Expr *e) : Decl(n) { | 15 | 15 | VarDecl::VarDecl(Identifier *n, Type *t, Expr *e) : Decl(n) { | |
Assert(n != NULL && t != NULL); | 16 | 16 | Assert(n != NULL && t != NULL); | |
(type=t)->SetParent(this); | 17 | 17 | (type=t)->SetParent(this); | |
if (e) (assignTo=e)->SetParent(this); | 18 | 18 | if (e) (assignTo=e)->SetParent(this); | |
typeq = NULL; | 19 | 19 | typeq = NULL; | |
} | 20 | 20 | } | |
21 | 21 | |||
VarDecl::VarDecl(Identifier *n, TypeQualifier *tq, Expr *e) : Decl(n) { | 22 | 22 | VarDecl::VarDecl(Identifier *n, TypeQualifier *tq, Expr *e) : Decl(n) { | |
Assert(n != NULL && tq != NULL); | 23 | 23 | Assert(n != NULL && tq != NULL); | |
(typeq=tq)->SetParent(this); | 24 | 24 | (typeq=tq)->SetParent(this); | |
if (e) (assignTo=e)->SetParent(this); | 25 | 25 | if (e) (assignTo=e)->SetParent(this); | |
type = NULL; | 26 | 26 | type = NULL; | |
} | 27 | 27 | } | |
28 | 28 | |||
VarDecl::VarDecl(Identifier *n, Type *t, TypeQualifier *tq, Expr *e) : Decl(n) { | 29 | 29 | VarDecl::VarDecl(Identifier *n, Type *t, TypeQualifier *tq, Expr *e) : Decl(n) { | |
Assert(n != NULL && t != NULL && tq != NULL); | 30 | 30 | Assert(n != NULL && t != NULL && tq != NULL); | |
(type=t)->SetParent(this); | 31 | 31 | (type=t)->SetParent(this); | |
(typeq=tq)->SetParent(this); | 32 | 32 | (typeq=tq)->SetParent(this); | |
if (e) (assignTo=e)->SetParent(this); | 33 | 33 | if (e) (assignTo=e)->SetParent(this); | |
} | 34 | 34 | } | |
35 | 35 | |||
void VarDecl::PrintChildren(int indentLevel) { | 36 | 36 | void VarDecl::PrintChildren(int indentLevel) { | |
if (typeq) typeq->Print(indentLevel+1); | 37 | 37 | if (typeq) typeq->Print(indentLevel+1); | |
if (type) type->Print(indentLevel+1); | 38 | 38 | if (type) type->Print(indentLevel+1); | |
if (id) id->Print(indentLevel+1); | 39 | 39 | if (id) id->Print(indentLevel+1); | |
if (assignTo) assignTo->Print(indentLevel+1, "(initializer) "); | 40 | 40 | if (assignTo) assignTo->Print(indentLevel+1, "(initializer) "); | |
} | 41 | 41 | } | |
42 | 42 | |||
FnDecl::FnDecl(Identifier *n, Type *r, List<VarDecl*> *d) : Decl(n) { | 43 | 43 | FnDecl::FnDecl(Identifier *n, Type *r, List<VarDecl*> *d) : Decl(n) { | |
Assert(n != NULL && r!= NULL && d != NULL); | 44 | 44 | Assert(n != NULL && r!= NULL && d != NULL); | |
(returnType=r)->SetParent(this); | 45 | 45 | (returnType=r)->SetParent(this); | |
(formals=d)->SetParentAll(this); | 46 | 46 | (formals=d)->SetParentAll(this); | |
body = NULL; | 47 | 47 | body = NULL; | |
returnTypeq = NULL; | 48 | 48 | returnTypeq = NULL; | |
} | 49 | 49 | } | |
50 | 50 | |||
FnDecl::FnDecl(Identifier *n, Type *r, TypeQualifier *rq, List<VarDecl*> *d) : Decl(n) { | 51 | 51 | FnDecl::FnDecl(Identifier *n, Type *r, TypeQualifier *rq, List<VarDecl*> *d) : Decl(n) { | |
Assert(n != NULL && r != NULL && rq != NULL&& d != NULL); | 52 | 52 | Assert(n != NULL && r != NULL && rq != NULL&& d != NULL); | |
(returnType=r)->SetParent(this); | 53 | 53 | (returnType=r)->SetParent(this); | |
(returnTypeq=rq)->SetParent(this); | 54 | 54 | (returnTypeq=rq)->SetParent(this); | |
(formals=d)->SetParentAll(this); | 55 | 55 | (formals=d)->SetParentAll(this); | |
body = NULL; | 56 | 56 | body = NULL; | |
} | 57 | 57 | } | |
58 | 58 | |||
void FnDecl::SetFunctionBody(Stmt *b) { | 59 | 59 | void FnDecl::SetFunctionBody(Stmt *b) { | |
(body=b)->SetParent(this); | 60 | 60 | (body=b)->SetParent(this); | |
} | 61 | 61 | } | |
62 | 62 | |||
void FnDecl::PrintChildren(int indentLevel) { | 63 | 63 | void FnDecl::PrintChildren(int indentLevel) { | |
if (returnType) returnType->Print(indentLevel+1, "(return type) "); | 64 | 64 | if (returnType) returnType->Print(indentLevel+1, "(return type) "); | |
if (id) id->Print(indentLevel+1); | 65 | 65 | if (id) id->Print(indentLevel+1); | |
if (formals) formals->PrintAll(indentLevel+1, "(formals) "); | 66 | 66 | if (formals) formals->PrintAll(indentLevel+1, "(formals) "); | |
if (body) body->Print(indentLevel+1, "(body) "); | 67 | 67 | if (body) body->Print(indentLevel+1, "(body) "); | |
} | 68 | 68 | } | |
69 | ||||
/* | 69 | 70 | /* | |
llvm::Value* VarDecl::Emit() { | 70 | 71 | llvm::Value* VarDecl::Emit() { | |
llvm::BasicBlock* b = irgen.GetBasicBlock(); | 71 | 72 | llvm::BasicBlock* b = irgen.GetBasicBlock(); | |
llvm::Value* val; | 72 | 73 | llvm::Value* val; | |
if(b) val = new llvm::AllocaInst(convertType(type), id->GetName(), b); | 73 | 74 | if(b) val = new llvm::AllocaInst(convertType(type), id->GetName(), b); | |
else { | 74 | 75 | else { | |
llvm::Constant* e = assignTo ? (llvm::Constant*)assignTo->Emit() : llvm::Constant::getNullValue(convertType(type)); | 75 | 76 | llvm::Constant* e = assignTo ? (llvm::Constant*)assignTo->Emit() : llvm::Constant::getNullValue(convertType(type)); | |
val = new llvm::GlobalVariable(*irgen.GetOrCreateModule("program"), convertType(type), false, llvm::GlobalValue::ExternalLinkage, e, ""); | 76 | 77 | val = new llvm::GlobalVariable(*irgen.GetOrCreateModule("program"), convertType(type), false, llvm::GlobalValue::ExternalLinkage, e, ""); | |
} | 77 | 78 | } | |
if(assignTo) val = new llvm::StoreInst(val, assignTo->Emit(), "", b); | 78 | 79 | if(assignTo) val = new llvm::StoreInst(val, assignTo->Emit(), "", b); | |
addToScope(id->GetName(), this, val); | 79 | 80 | addToScope(id->GetName(), this, val); | |
return val; | 80 | 81 | return val; | |
} | 81 | 82 | } | |
*/ | 82 | 83 | */ | |
llvm::Value * VarDecl::Emit(){ | 83 | 84 | llvm::Value * VarDecl::Emit(){ | |
Type * t = type; | 84 | 85 | Type * t = type; | |
llvm::Type * ltyp=convertType(t); | 85 | 86 | llvm::Type * ltyp=convertType(t); | |
llvm::Value * val; | 86 | 87 | llvm::Value * val; | |
llvm::Module *mod = irgen.GetOrCreateModule("program"); | 87 | 88 | llvm::Module *mod = irgen.GetOrCreateModule("program"); | |
if (global()){ | 88 | 89 | if (global()){ | |
val = new llvm::GlobalVariable(*mod, ltyp, false, llvm::GlobalValue::ExternalLinkage, llvm::Constant::getNullValue(ltyp), llvm::Twine(id->GetName())); | 89 | 90 | val = new llvm::GlobalVariable(*mod, ltyp, false, llvm::GlobalValue::ExternalLinkage, llvm::Constant::getNullValue(ltyp), llvm::Twine(id->GetName())); | |
addToScope(id->GetName(),this, val); | 90 | 91 | addToScope(id->GetName(),this, val); | |
} | 91 | 92 | } | |
else{ | 92 | 93 | else{ | |
val = new llvm::AllocaInst(ltyp, llvm::Twine(id->GetName()), irgen.GetBasicBlock()); | 93 | 94 | val = new llvm::AllocaInst(ltyp, llvm::Twine(id->GetName()), irgen.GetBasicBlock()); | |
addToScope(id->GetName(),this, val); | 94 | 95 | addToScope(id->GetName(),this, val); | |
} | 95 | 96 | } | |
return val; | 96 | 97 | return val; | |
} | 97 | 98 | } | |
98 | 99 | |||
99 | 100 | |||
/* | 100 | 101 | /* | |
llvm::Value* FnDecl::Emit() { | 101 | 102 | llvm::Value* FnDecl::Emit() { | |
llvm::BasicBlock* oldBlock = irgen.GetBasicBlock(); | 102 | 103 | llvm::BasicBlock* oldBlock = irgen.GetBasicBlock(); | |
llvm::LLVMContext* context = irgen.GetContext(); | 103 | 104 | llvm::LLVMContext* context = irgen.GetContext(); | |
pushScope(); | 104 | 105 | pushScope(); | |
vector<llvm::Type*> types; | 105 | 106 | vector<llvm::Type*> types; | |
for(int i = 0; i < formals->NumElements(); i++) { | 106 | 107 | for(int i = 0; i < formals->NumElements(); i++) { | |
types.push_back(convertType(formals->Nth(i)->GetType())); | 107 | 108 | types.push_back(convertType(formals->Nth(i)->GetType())); | |
} | 108 | 109 | } | |
llvm::FunctionType* ft = llvm::FunctionType::get(convertType(returnType), types, false); | 109 | 110 | llvm::FunctionType* ft = llvm::FunctionType::get(convertType(returnType), types, false); | |
popScope(); | 110 | 111 | popScope(); | |
llvm::Function* func = llvm::Function::Create(ft, llvm::Function::ExternalLinkage, id->GetName(), irgen.GetOrCreateModule("program")); | 111 | 112 | llvm::Function* func = llvm::Function::Create(ft, llvm::Function::ExternalLinkage, id->GetName(), irgen.GetOrCreateModule("program")); | |
llvm::BasicBlock * block = llvm::BasicBlock::Create(*context, "funcBlock", func); | 112 | 113 | llvm::BasicBlock * block = llvm::BasicBlock::Create(*context, "funcBlock", func); | |
irgen.SetBasicBlock(block); | 113 | 114 | irgen.SetBasicBlock(block); | |
irgen.SetFunction(func); | 114 | 115 | irgen.SetFunction(func); | |
for(int i = 0; i < formals->NumElements(); i++) { | 115 | 116 | for(int i = 0; i < formals->NumElements(); i++) { | |
formals->Nth(i)->Emit(); | 116 | 117 | formals->Nth(i)->Emit(); | |
} | 117 | 118 | } | |
body->Emit(); | 118 | 119 | body->Emit(); | |
if(!block->getTerminator()) { | 119 | 120 | if(!block->getTerminator()) { | |
llvm::Value* retVar = new llvm::AllocaInst(convertType(returnType), "", block); | 120 | 121 | llvm::Value* retVar = new llvm::AllocaInst(convertType(returnType), "", block); | |
llvm::Value* ret = new llvm::LoadInst(retVar, "", block); | 121 | 122 | llvm::Value* ret = new llvm::LoadInst(retVar, "", block); | |
llvm::ReturnInst::Create(*context, ret, block); | 122 | 123 | llvm::ReturnInst::Create(*context, ret, block); | |
} | 123 | 124 | } | |
irgen.SetBasicBlock(oldBlock); | 124 | 125 | irgen.SetBasicBlock(oldBlock); | |
return func; | 125 | 126 | return func; | |
} | 126 | 127 | } | |
*/ | 127 | 128 | */ | |
llvm::Value * FnDecl::Emit(){ | 128 | 129 | llvm::Value * FnDecl::Emit(){ | |
llvm::Module *mod = irgen.GetOrCreateModule("program"); | 129 | 130 | llvm::Module *mod = irgen.GetOrCreateModule("program"); | |
llvm::Type *rt = convertType(this->returnType); | 130 | 131 | llvm::Type *rt = convertType(this->returnType); | |
131 | 132 | |||
std::vector<llvm::Type *> ref; | 132 | 133 | std::vector<llvm::Type *> ref; | |
for (int i = 0; i < formals->NumElements(); i++){ | 133 | 134 | for (int i = 0; i < formals->NumElements(); i++){ | |
ref.push_back(convertType(formals->Nth(i)->GetType())); | 134 | 135 | ref.push_back(convertType(formals->Nth(i)->GetType())); | |
} | 135 | 136 | } | |
llvm::ArrayRef<llvm::Type *> ar(ref); | 136 | 137 | llvm::ArrayRef<llvm::Type *> ar(ref); | |
llvm::FunctionType * ft = llvm::FunctionType::get(rt, ar, false); | 137 | 138 | llvm::FunctionType * ft = llvm::FunctionType::get(rt, ar, false); | |
138 | 139 | |||
llvm::Value * funcval = mod->getOrInsertFunction(llvm::StringRef(this->GetIdentifier()->GetName()), ft); | 139 | 140 | llvm::Value * funcval = mod->getOrInsertFunction(llvm::StringRef(this->GetIdentifier()->GetName()), ft); | |
llvm::Function * fp = llvm::cast<llvm::Function>(funcval); | 140 | 141 | llvm::Function * fp = llvm::cast<llvm::Function>(funcval); | |
141 | 142 | |||
addToScope(id->GetName(),this, funcval); | 142 | 143 | addToScope(id->GetName(),this, funcval); | |
//TODO is this how you set it? | 143 | 144 | //TODO is this how you set it? | |
irgen.SetFunction(fp); | 144 | 145 | irgen.SetFunction(fp); | |
145 | 146 | |||
//SetName | 146 | 147 | //SetName | |
pushScope(); | 147 | 148 | pushScope(); | |
llvm::Function::arg_iterator args = fp->arg_begin(); | 148 | 149 | llvm::Function::arg_iterator args = fp->arg_begin(); | |
149 | 150 | |||
llvm::LLVMContext *context = irgen.GetContext(); | 150 | 151 | llvm::LLVMContext *context = irgen.GetContext(); | |
llvm::BasicBlock * varbb = llvm::BasicBlock::Create(*context, "entry", fp); | 151 | 152 | llvm::BasicBlock * varbb = llvm::BasicBlock::Create(*context, "entry", fp); |