summaryrefslogtreecommitdiff
path: root/node/FunctionNode.cc
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/FunctionNode.cc
parentfd21f31e654a97027799f0fdf3518fd639415121 (diff)
support for type alias
Diffstat (limited to 'node/FunctionNode.cc')
-rw-r--r--node/FunctionNode.cc36
1 files changed, 22 insertions, 14 deletions
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();
}