summaryrefslogtreecommitdiff
path: root/node/FunctionNode.cc
diff options
context:
space:
mode:
authorNagi5Yeq <wu@x-nagi.com>2020-05-31 17:49:34 +0800
committerNagi5Yeq <wu@x-nagi.com>2020-05-31 17:49:34 +0800
commitc2c6e5c7e620c32e7f420e8b9ac21df8855b444c (patch)
treec790ec3650c2f6caed9b59b304bc6a8bbdef1da8 /node/FunctionNode.cc
parent4a5bc55769804d003d6cd9f8c16eefb76bb53d1b (diff)
support for extern functions
Diffstat (limited to 'node/FunctionNode.cc')
-rw-r--r--node/FunctionNode.cc30
1 files changed, 30 insertions, 0 deletions
diff --git a/node/FunctionNode.cc b/node/FunctionNode.cc
index 97b1680..4fb5138 100644
--- a/node/FunctionNode.cc
+++ b/node/FunctionNode.cc
@@ -91,4 +91,34 @@ Value FunctionNode::CodeGen() {
return nullptr;
}
+ExternNode::ExternNode(Context* context, std::string&& name,
+ std::list<Declaration>&& arguments,
+ std::shared_ptr<TypeIdentifier> ReturnTypeIdentifier,
+ bool IsVariadic)
+ : FunctionNode(context, std::move(name), std::move(arguments),
+ std::list<std::shared_ptr<DeclNode>>(), ReturnTypeIdentifier,
+ nullptr)
+ , IsVariadic_(IsVariadic) {}
+
+Value ExternNode::CodeGen() {
+ llvm::Module* module = context_->GetModule();
+ 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)->GetType(); });
+ std::shared_ptr<Type> ReturnType = ReturnTypeIdentifier_->GetType();
+ std::shared_ptr<FunctionType> type =
+ manager->CreateFunctionType(ReturnType, params, IsVariadic_);
+ llvm::FunctionType* LLVMType =
+ llvm::cast<llvm::FunctionType>(type->GetLLVMType());
+ llvm::FunctionCallee callee = module->getOrInsertFunction(name_, LLVMType);
+ llvm::Function* function = llvm::cast<llvm::Function>(callee.getCallee());
+ function->setCallingConv(llvm::CallingConv::C);
+ context_->AddFunction(name_, {type, function});
+ Log(LogLevel::PCC_INFO, "extern function %s of type %s", name_.c_str(),
+ type->GetCommonName());
+ return nullptr;
+}
} // namespace pcc