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 | |
| parent | fd21f31e654a97027799f0fdf3518fd639415121 (diff) | |
support for type alias
Diffstat (limited to 'node')
| -rw-r--r-- | node/DeclNode.cc | 31 | ||||
| -rw-r--r-- | node/DeclNode.hh | 10 | ||||
| -rw-r--r-- | node/ExprNode.cc | 2 | ||||
| -rw-r--r-- | node/FunctionNode.cc | 36 | ||||
| -rw-r--r-- | node/FunctionNode.hh | 4 | ||||
| -rw-r--r-- | node/LiteralNode.cc | 3 |
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 |
