feat(sem)补充类型系统

feature/sem
mxr 3 weeks ago
parent a1ba450950
commit 2070193fcd

@ -41,6 +41,8 @@
namespace ir {
class Type;
class ArrayType;
class FunctionType;
class Value;
class User;
class ConstantValue;
@ -93,23 +95,79 @@ class Context {
class Type {
public:
enum class Kind { Void, Int32, PtrInt32 };
explicit Type(Kind k);
enum class Kind { Void, Int32, PtrInt32, Array, Function };
virtual ~Type() = default;
// 使用静态共享对象获取类型。
// 同一类型可直接比较返回值是否相等,例如:
// Type::GetInt32Type() == Type::GetInt32Type()
static const std::shared_ptr<Type>& GetVoidType();
static const std::shared_ptr<Type>& GetInt32Type();
static const std::shared_ptr<Type>& GetPtrInt32Type();
Kind GetKind() const;
bool IsVoid() const;
bool IsInt32() const;
bool IsPtrInt32() const;
static std::shared_ptr<ArrayType> GetArrayType(std::shared_ptr<Type> elem, std::vector<int> dims);
static std::shared_ptr<FunctionType> GetFunctionType(std::shared_ptr<Type> ret, std::vector<std::shared_ptr<Type>> params);
// 类型判断
Kind GetKind() const { return kind_; }
bool IsVoid() const { return kind_ == Kind::Void; }
bool IsInt32() const { return kind_ == Kind::Int32; }
bool IsPtrInt32() const { return kind_ == Kind::PtrInt32; }
bool IsArray() const { return kind_ == Kind::Array; }
bool IsFunction() const { return kind_ == Kind::Function; }
// 类型属性
virtual size_t Size() const; // 字节大小
virtual size_t Alignment() const; // 对齐要求
virtual bool IsComplete() const; // 是否为完整类型(非 void数组维度已知等
protected:
explicit Type(Kind k); // 构造函数 protected只能由工厂和派生类调用
private:
Kind kind_;
};
// 数组类型
class ArrayType : public Type {
public:
// 获取元素类型和维度
const std::shared_ptr<Type>& GetElementType() const { return elem_type_; }
const std::vector<int>& GetDimensions() const { return dims_; }
size_t GetElementCount() const; // 总元素个数
size_t Size() const override;
size_t Alignment() const override;
bool IsComplete() const override;
protected:
ArrayType(std::shared_ptr<Type> elem, std::vector<int> dims);
friend class Type; // 允许 Type::GetArrayType 构造
private:
std::shared_ptr<Type> elem_type_;
std::vector<int> dims_;
};
// 函数类型
class FunctionType : public Type {
public:
const std::shared_ptr<Type>& GetReturnType() const { return return_type_; }
const std::vector<std::shared_ptr<Type>>& GetParamTypes() const { return param_types_; }
size_t Size() const override; // 函数类型没有大小,通常返回 0
size_t Alignment() const override; // 无对齐要求
bool IsComplete() const override; // 函数类型视为完整
protected:
FunctionType(std::shared_ptr<Type> ret, std::vector<std::shared_ptr<Type>> params);
friend class Type;
private:
std::shared_ptr<Type> return_type_;
std::vector<std::shared_ptr<Type>> param_types_;
};
class Value {
public:
Value(std::shared_ptr<Type> ty, std::string name);

@ -1,31 +1,188 @@
// 当前仅支持 void、i32 和 i32*。
#include "ir/IR.h"
#include <cassert>
namespace ir {
Type::Type(Kind k) : kind_(k) {}
size_t Type::Size() const {
switch (kind_) {
case Kind::Void: return 0;
case Kind::Int32: return 4;
case Kind::PtrInt32: return 8; // 假设 64 位平台
default: return 0; // 派生类应重写
}
}
size_t Type::Alignment() const {
switch (kind_) {
case Kind::Int32: return 4;
case Kind::PtrInt32: return 8;
default: return 1; // void 和复合类型由派生类处理
}
}
bool Type::IsComplete() const {
// void 视为完整类型但不能有对象int 和指针都是完整类型
return kind_ != Kind::Void;
}
const std::shared_ptr<Type>& Type::GetVoidType() {
static const std::shared_ptr<Type> type = std::make_shared<Type>(Kind::Void);
static const std::shared_ptr<Type> type = std::shared_ptr<Type>(new Type(Kind::Void));
return type;
}
const std::shared_ptr<Type>& Type::GetInt32Type() {
static const std::shared_ptr<Type> type = std::make_shared<Type>(Kind::Int32);
static const std::shared_ptr<Type> type = std::shared_ptr<Type>(new Type(Kind::Int32));
return type;
}
const std::shared_ptr<Type>& Type::GetPtrInt32Type() {
static const std::shared_ptr<Type> type = std::make_shared<Type>(Kind::PtrInt32);
static const std::shared_ptr<Type> type = std::shared_ptr<Type>(new Type(Kind::PtrInt32));
return type;
}
Type::Kind Type::GetKind() const { return kind_; }
// ---------- 数组类型缓存 ----------
// 使用自定义键类型保证唯一性:元素类型指针 + 维度向量
struct ArrayKey {
const Type* elem_type;
std::vector<int> dims;
bool operator==(const ArrayKey& other) const {
return elem_type == other.elem_type && dims == other.dims;
}
};
struct ArrayKeyHash {
std::size_t operator()(const ArrayKey& key) const {
std::size_t h = std::hash<const Type*>{}(key.elem_type);
for (int d : key.dims) {
h ^= std::hash<int>{}(d) + 0x9e3779b9 + (h << 6) + (h >> 2);
}
return h;
}
};
static std::unordered_map<ArrayKey, std::weak_ptr<ArrayType>, ArrayKeyHash>& GetArrayCache() {
static std::unordered_map<ArrayKey, std::weak_ptr<ArrayType>, ArrayKeyHash> cache;
return cache;
}
std::shared_ptr<ArrayType> Type::GetArrayType(std::shared_ptr<Type> elem,
std::vector<int> dims) {
// 检查维度合法性
for (int d : dims) {
if (d <= 0) {
// SysY 数组维度必须为正整数常量表达式,这里假设已检查
return nullptr;
}
}
ArrayKey key{elem.get(), dims};
auto& cache = GetArrayCache();
auto it = cache.find(key);
if (it != cache.end()) {
auto ptr = it->second.lock();
if (ptr) return ptr;
}
auto arr = std::shared_ptr<ArrayType>(new ArrayType(std::move(elem), std::move(dims)));
cache[key] = arr;
return arr;
}
// ---------- 函数类型缓存 ----------
struct FunctionKey {
const Type* return_type;
std::vector<const Type*> param_types;
bool operator==(const FunctionKey& other) const {
return return_type == other.return_type && param_types == other.param_types;
}
};
struct FunctionKeyHash {
std::size_t operator()(const FunctionKey& key) const {
std::size_t h = std::hash<const Type*>{}(key.return_type);
for (const Type* t : key.param_types) {
h ^= std::hash<const Type*>{}(t) + 0x9e3779b9 + (h << 6) + (h >> 2);
}
return h;
}
};
static std::unordered_map<FunctionKey, std::weak_ptr<FunctionType>, FunctionKeyHash>& GetFunctionCache() {
static std::unordered_map<FunctionKey, std::weak_ptr<FunctionType>, FunctionKeyHash> cache;
return cache;
}
std::shared_ptr<FunctionType> Type::GetFunctionType(std::shared_ptr<Type> ret,
std::vector<std::shared_ptr<Type>> params) {
// 提取裸指针用于键(保证唯一性,因为 shared_ptr 指向同一对象)
std::vector<const Type*> param_ptrs;
param_ptrs.reserve(params.size());
for (const auto& p : params) {
param_ptrs.push_back(p.get());
}
FunctionKey key{ret.get(), std::move(param_ptrs)};
auto& cache = GetFunctionCache();
auto it = cache.find(key);
if (it != cache.end()) {
auto ptr = it->second.lock();
if (ptr) return ptr;
}
auto func = std::shared_ptr<FunctionType>(new FunctionType(std::move(ret), std::move(params)));
cache[key] = func;
return func;
}
// ---------- ArrayType 实现 ----------
ArrayType::ArrayType(std::shared_ptr<Type> elem, std::vector<int> dims)
: Type(Kind::Array), elem_type_(std::move(elem)), dims_(std::move(dims)) {
// 数组元素类型必须是完整类型
assert(elem_type_ && elem_type_->IsComplete());
}
size_t ArrayType::GetElementCount() const {
size_t count = 1;
for (int d : dims_) count *= d;
return count;
}
size_t ArrayType::Size() const {
return GetElementCount() * elem_type_->Size();
}
bool Type::IsVoid() const { return kind_ == Kind::Void; }
size_t ArrayType::Alignment() const {
// 数组对齐等于其元素对齐
return elem_type_->Alignment();
}
bool Type::IsInt32() const { return kind_ == Kind::Int32; }
bool ArrayType::IsComplete() const {
// 维度已确定且元素类型完整,则数组完整
return !dims_.empty() && elem_type_->IsComplete();
}
bool Type::IsPtrInt32() const { return kind_ == Kind::PtrInt32; }
// ---------- FunctionType 实现 ----------
FunctionType::FunctionType(std::shared_ptr<Type> ret,
std::vector<std::shared_ptr<Type>> params)
: Type(Kind::Function), return_type_(std::move(ret)), param_types_(std::move(params)) {}
size_t FunctionType::Size() const {
// 函数类型没有运行时大小,通常用于类型检查,返回 0
return 0;
}
size_t FunctionType::Alignment() const {
// 不对齐
return 1;
}
bool FunctionType::IsComplete() const {
// 函数类型总是完整的(只要返回类型完整,但 SysY 中 void 也视为完整)
return true;
}
} // namespace ir

Loading…
Cancel
Save