summaryrefslogtreecommitdiff
path: root/node
diff options
context:
space:
mode:
authorNagi5Yeq <wu@x-nagi.com>2020-05-31 04:03:00 +0800
committerNagi5Yeq <wu@x-nagi.com>2020-05-31 04:03:00 +0800
commitbd44c9eaef1f4dcbbd98d4489885566b6c7e5138 (patch)
treed664ec481b99e04386c47526b56085320edd9cde /node
parentfd21f31e654a97027799f0fdf3518fd639415121 (diff)
support for type alias
Diffstat (limited to 'node')
-rw-r--r--node/DeclNode.cc31
-rw-r--r--node/DeclNode.hh10
-rw-r--r--node/ExprNode.cc2
-rw-r--r--node/FunctionNode.cc36
-rw-r--r--node/FunctionNode.hh4
-rw-r--r--node/LiteralNode.cc3
6 files changed, 59 insertions, 27 deletions
diff --git a/node/DeclNode.cc b/node/DeclNode.cc
index 929bc70..4d2f8aa 100644
--- a/node/DeclNode.cc
+++ b/node/DeclNode.cc
@@ -2,6 +2,7 @@
#include "DeclNode.hh"
#include "Log.hh"
+#include "TypeIdentifier.hh"
namespace pcc {
DeclNode::DeclNode(Context* context, VariableList* scope)
@@ -22,23 +23,23 @@ Value VarDeclNode::CodeGen() {
TypeManager* manager = context_->GetTypeManager();
if (scope_ != nullptr) {
for (auto&& decl : decls_) {
- Value value =
- builder->CreateAlloca(std::get<1>(decl)->GetLLVMType());
- scope_->Add(std::get<0>(decl),
- {manager->GetPointerType(std::get<1>(decl)), value});
+ std::shared_ptr<Type> type = std::get<1>(decl)->GetType();
+ Value value = builder->CreateAlloca(type->GetLLVMType());
+ scope_->AddVariable(std::get<0>(decl),
+ {manager->GetPointerType(type), value});
}
return nullptr;
}
// global variable case
VariableList* globals = context_->GetGlobals();
for (auto&& decl : decls_) {
- std::shared_ptr<Type> type = std::get<1>(decl);
+ std::shared_ptr<Type> type = std::get<1>(decl)->GetType();
llvm::GlobalValue* value = new llvm::GlobalVariable(
*context_->GetModule(), type->GetLLVMType(), false,
llvm::GlobalVariable::PrivateLinkage, type->GetZeroInitializer());
value->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
- globals->Add(std::get<0>(decl),
- {manager->GetPointerType(std::get<1>(decl)), value});
+ globals->AddVariable(std::get<0>(decl),
+ {manager->GetPointerType(type), value});
}
return nullptr;
}
@@ -62,10 +63,22 @@ Value ConstDeclNode::CodeGen() {
llvm::GlobalValue::PrivateLinkage,
llvm::cast<llvm::Constant>(value));
constant->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
- scope_->Add(std::get<0>(decl),
- {manager->GetPointerType(type), constant});
+ scope_->AddVariable(std::get<0>(decl),
+ {manager->GetPointerType(type), constant});
}
return nullptr;
}
+TypeDeclNode::TypeDeclNode(Context* context, VariableList* scope,
+ std::list<Declaration>&& decls)
+ : DeclNode(context, scope)
+ , decls_(std::move(decls)) {}
+
+Value TypeDeclNode::CodeGen() {
+ scope_ = (scope_ == nullptr ? context_->GetGlobals() : scope_);
+ for (auto&& decl : decls_) {
+ scope_->AddTypeAlias(std::get<0>(decl), std::get<1>(decl)->GetType());
+ }
+ return nullptr;
+}
} // namespace pcc
diff --git a/node/DeclNode.hh b/node/DeclNode.hh
index f51fa1b..3858fc6 100644
--- a/node/DeclNode.hh
+++ b/node/DeclNode.hh
@@ -42,6 +42,16 @@ class ConstDeclNode : public DeclNode {
protected:
std::list<Constant> decls_;
};
+
+class TypeDeclNode : public DeclNode {
+ public:
+ TypeDeclNode(Context* context, VariableList* scope,
+ std::list<Declaration>&& decls);
+ virtual Value CodeGen() override;
+
+ protected:
+ std::list<Declaration> decls_;
+};
} // namespace pcc
#endif // !PCC_DECLNODE_HH
diff --git a/node/ExprNode.cc b/node/ExprNode.cc
index 2dce99f..e15d39e 100644
--- a/node/ExprNode.cc
+++ b/node/ExprNode.cc
@@ -157,7 +157,7 @@ IdentifierNode::IdentifierNode(Context* context, const std::string& name)
, name_(name) {}
Value IdentifierNode::CodeGen() {
- Variable var = context_->GetCurrentScope()->Find(name_);
+ Variable var = context_->GetCurrentScope()->FindVariable(name_);
type_ = std::get<0>(var);
return std::get<1>(var);
}
diff --git a/node/FunctionNode.cc b/node/FunctionNode.cc
index c85297b..97b1680 100644
--- a/node/FunctionNode.cc
+++ b/node/FunctionNode.cc
@@ -7,17 +7,19 @@
#include "DeclNode.hh"
#include "FunctionNode.hh"
#include "Log.hh"
+#include "TypeIdentifier.hh"
namespace pcc {
FunctionNode::FunctionNode(
Context* context, std::string&& name, std::list<Declaration>&& arguments,
std::list<std::shared_ptr<DeclNode>>&& LocalDeclarations,
- std::shared_ptr<Type> ReturnType, std::shared_ptr<StatementListNode> body)
+ std::shared_ptr<TypeIdentifier> ReturnTypeIdentifier,
+ std::shared_ptr<StatementListNode> body)
: BaseNode(context)
, name_(std::move(name))
, arguments_(std::move(arguments))
, LocalDeclarations_(std::move(LocalDeclarations))
- , ReturnType_(ReturnType)
+ , ReturnTypeIdentifier_(ReturnTypeIdentifier)
, locals_(context->GetGlobals())
, body_(body) {
for (auto&& decl : LocalDeclarations_) {
@@ -30,45 +32,51 @@ Value FunctionNode::CodeGen() {
llvm::IRBuilder<>* builder = context_->GetBuilder();
TypeManager* manager = context_->GetTypeManager();
std::vector<std::shared_ptr<Type>> params(arguments_.size());
- std::transform(arguments_.cbegin(), arguments_.cend(), params.begin(),
- [](const Declaration& decl) { return std::get<1>(decl); });
+ std::transform(
+ arguments_.cbegin(), arguments_.cend(), params.begin(),
+ [](const Declaration& decl) { return std::get<1>(decl)->GetType(); });
+ std::shared_ptr<Type> ReturnType = ReturnTypeIdentifier_->GetType();
std::shared_ptr<FunctionType> type =
- manager->CreateFunctionType(ReturnType_, params);
+ manager->CreateFunctionType(ReturnType, params);
llvm::FunctionType* LLVMType =
llvm::cast<llvm::FunctionType>(type->GetLLVMType());
llvm::Function* function = llvm::Function::Create(
LLVMType, llvm::GlobalValue::ExternalLinkage, name_, *module);
function->setCallingConv(llvm::CallingConv::C);
+
context_->AddFunction(name_, {type, function});
llvm::BasicBlock* block =
llvm::BasicBlock::Create(GlobalLLVMContext, name_, function);
Log(LogLevel::PCC_INFO, "generating function %s of type %s", name_.c_str(),
type->GetCommonName());
builder->SetInsertPoint(block);
+ context_->PushScope(&locals_);
// alloc arguments
llvm::Function::arg_iterator ArgIt = function->arg_begin();
+ decltype(params)::iterator ParamIt = params.begin();
for (auto&& arg : arguments_) {
- Value ArgValue = builder->CreateAlloca(std::get<1>(arg)->GetLLVMType());
- builder->CreateStore(ArgIt++, ArgValue);
- locals_.Add(std::get<0>(arg),
- {manager->GetPointerType(std::get<1>(arg)), ArgValue});
+ std::shared_ptr<Type> ArgType = *ParamIt;
+ Value ArgValue = builder->CreateAlloca(ArgType->GetLLVMType());
+ builder->CreateStore(ArgIt, ArgValue);
+ locals_.AddVariable(std::get<0>(arg),
+ {manager->GetPointerType(ArgType), ArgValue});
+ ++ArgIt, ++ParamIt;
}
// alloc local variables
for (auto&& decl : LocalDeclarations_) {
decl->CodeGen();
}
Value rv = nullptr;
- bool IsVoid = ReturnType_ == manager->GetBuiltinType(BuiltinType::VOID);
+ bool IsVoid = ReturnType == manager->GetBuiltinType(BuiltinType::VOID);
if (IsVoid == false) {
// create a variable with the same name as the function for return value
- rv = builder->CreateAlloca(ReturnType_->GetLLVMType());
- locals_.Add(name_, {manager->GetPointerType(ReturnType_), rv});
+ rv = builder->CreateAlloca(ReturnType->GetLLVMType());
+ locals_.AddVariable(name_, {manager->GetPointerType(ReturnType), rv});
}
// push the function scope variables
- context_->PushScope(&locals_);
body_->CodeGen();
if (IsVoid == false) {
- builder->CreateRet(builder->CreateLoad(ReturnType_->GetLLVMType(), rv));
+ builder->CreateRet(builder->CreateLoad(ReturnType->GetLLVMType(), rv));
} else {
builder->CreateRetVoid();
}
diff --git a/node/FunctionNode.hh b/node/FunctionNode.hh
index d317402..e939121 100644
--- a/node/FunctionNode.hh
+++ b/node/FunctionNode.hh
@@ -13,7 +13,7 @@ class FunctionNode : public BaseNode {
FunctionNode(Context* context, std::string&& name,
std::list<Declaration>&& arguments,
std::list<std::shared_ptr<DeclNode>>&& LocalDeclarations,
- std::shared_ptr<Type> ReturnType,
+ std::shared_ptr<TypeIdentifier> ReturnTypeIdentifier,
std::shared_ptr<StatementListNode> body);
virtual Value CodeGen() override;
@@ -21,7 +21,7 @@ class FunctionNode : public BaseNode {
std::string name_;
std::list<Declaration> arguments_;
std::list<std::shared_ptr<DeclNode>> LocalDeclarations_;
- std::shared_ptr<Type> ReturnType_;
+ std::shared_ptr<TypeIdentifier> ReturnTypeIdentifier_;
VariableList locals_;
std::shared_ptr<StatementListNode> body_;
};
diff --git a/node/LiteralNode.cc b/node/LiteralNode.cc
index 5523da6..43bddb6 100644
--- a/node/LiteralNode.cc
+++ b/node/LiteralNode.cc
@@ -46,6 +46,7 @@ Value StringLiteralNode::CodeGen() {
GlobalString->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
Value ZeroIndex =
llvm::ConstantInt::get(pointer->GetIndexType()->GetLLVMType(), 0, true);
- return builder->CreateInBoundsGEP(GlobalString, {ZeroIndex, ZeroIndex});
+ Value indices[2] = {ZeroIndex, ZeroIndex};
+ return builder->CreateInBoundsGEP(GlobalString, indices);
}
} // namespace pcc