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

// 支持 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