forked from NUDT-compiler/nudt-compiler-cpp
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
80 lines
2.0 KiB
80 lines
2.0 KiB
#include "ir/IR.h"
|
|
|
|
#include <algorithm>
|
|
#include <stdexcept>
|
|
|
|
namespace ir {
|
|
|
|
Function::Function(std::string name, std::shared_ptr<Type> function_type,
|
|
bool is_declaration)
|
|
: GlobalValue(std::move(function_type), std::move(name)),
|
|
is_declaration_(is_declaration) {
|
|
if (!type_ || !type_->IsFunction()) {
|
|
throw std::runtime_error("Function 需要 function type");
|
|
}
|
|
}
|
|
|
|
const std::shared_ptr<Type>& Function::GetFunctionType() const { return type_; }
|
|
|
|
const std::shared_ptr<Type>& Function::GetReturnType() const {
|
|
return type_->GetReturnType();
|
|
}
|
|
|
|
const std::vector<std::unique_ptr<Argument>>& Function::GetArguments() const {
|
|
return arguments_;
|
|
}
|
|
|
|
Argument* Function::AddArgument(std::shared_ptr<Type> ty, const std::string& name) {
|
|
auto arg = std::make_unique<Argument>(std::move(ty), name, arguments_.size(), this);
|
|
auto* ptr = arg.get();
|
|
arguments_.push_back(std::move(arg));
|
|
return ptr;
|
|
}
|
|
|
|
BasicBlock* Function::CreateBlock(const std::string& name) {
|
|
if (is_declaration_) {
|
|
throw std::runtime_error("声明函数不能创建基本块");
|
|
}
|
|
auto block = std::make_unique<BasicBlock>(name);
|
|
auto* ptr = block.get();
|
|
ptr->SetParent(this);
|
|
blocks_.push_back(std::move(block));
|
|
if (!entry_) {
|
|
entry_ = ptr;
|
|
}
|
|
return ptr;
|
|
}
|
|
|
|
BasicBlock* Function::GetEntry() { return entry_; }
|
|
|
|
const BasicBlock* Function::GetEntry() const { return entry_; }
|
|
|
|
bool Function::EraseBlock(BasicBlock* block) {
|
|
auto it =
|
|
std::find_if(blocks_.begin(), blocks_.end(),
|
|
[&](const std::unique_ptr<BasicBlock>& candidate) {
|
|
return candidate.get() == block;
|
|
});
|
|
if (it == blocks_.end()) {
|
|
return false;
|
|
}
|
|
if (entry_ == block) {
|
|
entry_ = nullptr;
|
|
}
|
|
blocks_.erase(it);
|
|
if (!entry_ && !blocks_.empty()) {
|
|
entry_ = blocks_.front().get();
|
|
}
|
|
return true;
|
|
}
|
|
|
|
std::vector<std::unique_ptr<BasicBlock>>& Function::GetBlocks() {
|
|
return blocks_;
|
|
}
|
|
|
|
const std::vector<std::unique_ptr<BasicBlock>>& Function::GetBlocks() const {
|
|
return blocks_;
|
|
}
|
|
|
|
} // namespace ir
|