From bd44c9eaef1f4dcbbd98d4489885566b6c7e5138 Mon Sep 17 00:00:00 2001 From: Nagi5Yeq Date: Sun, 31 May 2020 04:03:00 +0800 Subject: support for type alias --- node/FunctionNode.cc | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) (limited to 'node/FunctionNode.cc') 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&& arguments, std::list>&& LocalDeclarations, - std::shared_ptr ReturnType, std::shared_ptr body) + std::shared_ptr ReturnTypeIdentifier, + std::shared_ptr 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> 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 ReturnType = ReturnTypeIdentifier_->GetType(); std::shared_ptr type = - manager->CreateFunctionType(ReturnType_, params); + manager->CreateFunctionType(ReturnType, params); llvm::FunctionType* LLVMType = llvm::cast(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 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(); } -- cgit