summaryrefslogtreecommitdiff
path: root/node/DeclNode.cc
diff options
context:
space:
mode:
authorNagi5Yeq <wu@x-nagi.com>2020-05-30 00:25:03 +0800
committerNagi5Yeq <wu@x-nagi.com>2020-05-30 00:25:03 +0800
commit56d68765016fc7aa68fe7b522de5e84c7a12123a (patch)
treeba9828637913aa40bc1b1509c5127be9bded3a6e /node/DeclNode.cc
parentf15a071f6d599d2a21083dfb041b18db8d482949 (diff)
global variable, constant support
Diffstat (limited to 'node/DeclNode.cc')
-rw-r--r--node/DeclNode.cc55
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;
}