diff options
| author | Nagi5Yeq <wu@x-nagi.com> | 2020-05-31 04:03:00 +0800 |
|---|---|---|
| committer | Nagi5Yeq <wu@x-nagi.com> | 2020-05-31 04:03:00 +0800 |
| commit | bd44c9eaef1f4dcbbd98d4489885566b6c7e5138 (patch) | |
| tree | d664ec481b99e04386c47526b56085320edd9cde /node/FunctionNode.cc | |
| parent | fd21f31e654a97027799f0fdf3518fd639415121 (diff) | |
support for type alias
Diffstat (limited to 'node/FunctionNode.cc')
| -rw-r--r-- | node/FunctionNode.cc | 36 |
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(); } |
