// 支持 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 elem, size_t count) : kind_(k), elem_type_(std::move(elem)), array_size_(count) {} Type::Type(Kind k, std::shared_ptr ret, std::vector> 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::GetVoidType() { static const std::shared_ptr type = std::make_shared(Kind::Void); return type; } const std::shared_ptr& Type::GetInt1Type() { static const std::shared_ptr type = std::make_shared(Kind::Int1); return type; } const std::shared_ptr& Type::GetInt32Type() { static const std::shared_ptr type = std::make_shared(Kind::Int32); return type; } const std::shared_ptr& Type::GetFloatType() { static const std::shared_ptr type = std::make_shared(Kind::Float); return type; } const std::shared_ptr& Type::GetLabelType() { static const std::shared_ptr type = std::make_shared(Kind::Label); return type; } std::shared_ptr Type::GetPointerType(std::shared_ptr elem) { if (!elem) { throw std::runtime_error("PointerType 缺少 element type"); } return std::make_shared(Kind::Pointer, std::move(elem), 0); } std::shared_ptr Type::GetArrayType(std::shared_ptr elem, size_t count) { if (!elem) { throw std::runtime_error("ArrayType 缺少 element type"); } return std::make_shared(Kind::Array, std::move(elem), count); } std::shared_ptr Type::GetFunctionType( std::shared_ptr ret, std::vector> params, bool is_vararg) { if (!ret) { throw std::runtime_error("FunctionType 缺少 return type"); } return std::make_shared(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::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::GetReturnType() const { if (!IsFunction()) { throw std::runtime_error("Type 不是 function"); } return ret_type_; } const std::vector>& 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