diff options
| author | Nagi5Yeq <wu@x-nagi.com> | 2020-05-30 00:25:03 +0800 |
|---|---|---|
| committer | Nagi5Yeq <wu@x-nagi.com> | 2020-05-30 00:25:03 +0800 |
| commit | 56d68765016fc7aa68fe7b522de5e84c7a12123a (patch) | |
| tree | ba9828637913aa40bc1b1509c5127be9bded3a6e /node/DeclNode.cc | |
| parent | f15a071f6d599d2a21083dfb041b18db8d482949 (diff) | |
global variable, constant support
Diffstat (limited to 'node/DeclNode.cc')
| -rw-r--r-- | node/DeclNode.cc | 55 |
1 files changed, 47 insertions, 8 deletions
diff --git a/node/DeclNode.cc b/node/DeclNode.cc index 0fc3b89..00fd8e2 100644 --- a/node/DeclNode.cc +++ b/node/DeclNode.cc @@ -3,19 +3,58 @@ #include "DeclNode.hh" namespace pcc { -VarDeclNode::VarDeclNode(Context* context, VariableList* scope, - std::list<Declaration> decls) +DeclNode::DeclNode(Context* context, VariableList* scope) : BaseNode(context) - , scope_(scope) - , decls_(decls) {} + , scope_(scope) {} + +void DeclNode::SetScope(VariableList* scope) { scope_ = scope; } -void VarDeclNode::SetScope(VariableList* scope) { scope_ = scope; } +VarDeclNode::VarDeclNode(Context* context, VariableList* scope, + std::list<Declaration>&& decls) + : DeclNode(context, scope) + , decls_(std::move(decls)) {} +// if the scope is nullptr, this vardecl is in global scope. global variables +// are static, while local variables are allocated on stack. Value VarDeclNode::CodeGen() { llvm::IRBuilder<>* builder = context_->GetBuilder(); - for (auto& decl : decls_) { - Value value = builder->CreateAlloca(std::get<1>(decl)->GetLLVMType()); - scope_->Add(std::get<0>(decl), {std::get<1>(decl), value}); + if (scope_ != nullptr) { + for (auto&& decl : decls_) { + Value value = + builder->CreateAlloca(std::get<1>(decl)->GetLLVMType()); + scope_->Add(std::get<0>(decl), {std::get<1>(decl), value}); + } + return nullptr; + } + // global variable case + VariableList* globals = context_->GetGlobals(); + for (auto&& decl : decls_) { + llvm::Constant* value = new llvm::GlobalVariable( + *context_->GetModule(), std::get<1>(decl)->GetLLVMType(), false, + llvm::GlobalVariable::PrivateLinkage, nullptr); + globals->Add(std::get<0>(decl), {std::get<1>(decl), value}); + } + return nullptr; +} + +ConstDeclNode::ConstDeclNode(Context* context, VariableList* scope, + std::list<Constant>&& decls) + : DeclNode(context, scope) + , decls_(std::move(decls)) {} + +// for constants, we don't need to allocate them on stack, both global and local +// constants are static. +Value ConstDeclNode::CodeGen() { + scope_ = (scope_ == nullptr ? context_->GetGlobals() : scope_); + for (auto&& decl : decls_) { + std::shared_ptr<ExprNode> ValueNode = std::get<1>(decl); + Value value = ValueNode->CodeGen(); + std::shared_ptr<Type> type = ValueNode->GetType(); + llvm::Constant* constant = new llvm::GlobalVariable( + *context_->GetModule(), type->GetLLVMType(), true, + llvm::GlobalValue::PrivateLinkage, + llvm::cast<llvm::Constant>(value)); + scope_->Add(std::get<0>(decl), {type, constant}); } return nullptr; } |
