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.
149 lines
4.3 KiB
149 lines
4.3 KiB
// 支持 void/i1/i32/float/ptr/array/function/label。
|
|
#include "ir/IR.h"
|
|
|
|
namespace ir {
|
|
|
|
Type::Type(Kind k) : kind_(k) {}
|
|
|
|
Type::Type(Kind k, std::shared_ptr<Type> elem, size_t count)
|
|
: kind_(k), elem_type_(std::move(elem)), array_size_(count) {}
|
|
|
|
Type::Type(Kind k, std::shared_ptr<Type> ret,
|
|
std::vector<std::shared_ptr<Type>> params, bool is_vararg)
|
|
: kind_(k), ret_type_(std::move(ret)), param_types_(std::move(params)),
|
|
is_vararg_(is_vararg) {}
|
|
|
|
const std::shared_ptr<Type>& Type::GetVoidType() {
|
|
static const std::shared_ptr<Type> type = std::make_shared<Type>(Kind::Void);
|
|
return type;
|
|
}
|
|
|
|
const std::shared_ptr<Type>& Type::GetInt1Type() {
|
|
static const std::shared_ptr<Type> type = std::make_shared<Type>(Kind::Int1);
|
|
return type;
|
|
}
|
|
|
|
const std::shared_ptr<Type>& Type::GetInt32Type() {
|
|
static const std::shared_ptr<Type> type = std::make_shared<Type>(Kind::Int32);
|
|
return type;
|
|
}
|
|
|
|
const std::shared_ptr<Type>& Type::GetFloatType() {
|
|
static const std::shared_ptr<Type> type = std::make_shared<Type>(Kind::Float);
|
|
return type;
|
|
}
|
|
|
|
const std::shared_ptr<Type>& Type::GetLabelType() {
|
|
static const std::shared_ptr<Type> type = std::make_shared<Type>(Kind::Label);
|
|
return type;
|
|
}
|
|
|
|
std::shared_ptr<Type> Type::GetPointerType(std::shared_ptr<Type> elem) {
|
|
if (!elem) {
|
|
throw std::runtime_error("PointerType 缺少 element type");
|
|
}
|
|
return std::make_shared<Type>(Kind::Pointer, std::move(elem), 0);
|
|
}
|
|
|
|
std::shared_ptr<Type> Type::GetArrayType(std::shared_ptr<Type> elem,
|
|
size_t count) {
|
|
if (!elem) {
|
|
throw std::runtime_error("ArrayType 缺少 element type");
|
|
}
|
|
return std::make_shared<Type>(Kind::Array, std::move(elem), count);
|
|
}
|
|
|
|
std::shared_ptr<Type> Type::GetFunctionType(
|
|
std::shared_ptr<Type> ret, std::vector<std::shared_ptr<Type>> params,
|
|
bool is_vararg) {
|
|
if (!ret) {
|
|
throw std::runtime_error("FunctionType 缺少 return type");
|
|
}
|
|
return std::make_shared<Type>(Kind::Function, std::move(ret),
|
|
std::move(params), is_vararg);
|
|
}
|
|
|
|
Type::Kind Type::GetKind() const { return kind_; }
|
|
|
|
bool Type::IsVoid() const { return kind_ == Kind::Void; }
|
|
|
|
bool Type::IsInt1() const { return kind_ == Kind::Int1; }
|
|
|
|
bool Type::IsInt32() const { return kind_ == Kind::Int32; }
|
|
|
|
bool Type::IsFloat() const { return kind_ == Kind::Float; }
|
|
|
|
bool Type::IsPointer() const { return kind_ == Kind::Pointer; }
|
|
|
|
bool Type::IsArray() const { return kind_ == Kind::Array; }
|
|
|
|
bool Type::IsFunction() const { return kind_ == Kind::Function; }
|
|
|
|
bool Type::IsLabel() const { return kind_ == Kind::Label; }
|
|
|
|
const std::shared_ptr<Type>& Type::GetElementType() const {
|
|
if (!elem_type_) {
|
|
throw std::runtime_error("Type 没有 element type");
|
|
}
|
|
return elem_type_;
|
|
}
|
|
|
|
size_t Type::GetArraySize() const {
|
|
if (!IsArray()) {
|
|
throw std::runtime_error("Type 不是 array");
|
|
}
|
|
return array_size_;
|
|
}
|
|
|
|
const std::shared_ptr<Type>& Type::GetReturnType() const {
|
|
if (!IsFunction()) {
|
|
throw std::runtime_error("Type 不是 function");
|
|
}
|
|
return ret_type_;
|
|
}
|
|
|
|
const std::vector<std::shared_ptr<Type>>& Type::GetParamTypes() const {
|
|
if (!IsFunction()) {
|
|
throw std::runtime_error("Type 不是 function");
|
|
}
|
|
return param_types_;
|
|
}
|
|
|
|
bool Type::IsVarArg() const {
|
|
if (!IsFunction()) {
|
|
throw std::runtime_error("Type 不是 function");
|
|
}
|
|
return is_vararg_;
|
|
}
|
|
|
|
bool Type::Equals(const Type& other) const {
|
|
if (kind_ != other.kind_) return false;
|
|
switch (kind_) {
|
|
case Kind::Pointer:
|
|
return elem_type_ && other.elem_type_ &&
|
|
elem_type_->Equals(*other.elem_type_);
|
|
case Kind::Array:
|
|
return array_size_ == other.array_size_ && elem_type_ &&
|
|
other.elem_type_ && elem_type_->Equals(*other.elem_type_);
|
|
case Kind::Function: {
|
|
if (!ret_type_ || !other.ret_type_ ||
|
|
!ret_type_->Equals(*other.ret_type_) ||
|
|
is_vararg_ != other.is_vararg_ ||
|
|
param_types_.size() != other.param_types_.size()) {
|
|
return false;
|
|
}
|
|
for (size_t i = 0; i < param_types_.size(); ++i) {
|
|
if (!param_types_[i] || !other.param_types_[i] ||
|
|
!param_types_[i]->Equals(*other.param_types_[i])) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
default:
|
|
return true;
|
|
}
|
|
}
|
|
|
|
} // namespace ir
|