CompilerSysY/include/llir_type.h
2023-06-14 17:37:08 +08:00

163 lines
4.8 KiB
C++

#pragma once
#include "common.h"
#include <cassert>
#include <memory>
#include <string>
#include <vector>
namespace CompSysY {
DEF_PTR_T(Type);
DEF_PTR_T(IntegerType);
DEF_PTR_T(VoidType);
DEF_PTR_T(LabelType);
DEF_PTR_T(ArrayType);
DEF_PTR_T(PointerType);
DEF_PTR_T(FunctionType);
class Type {
public:
enum class TypeTag {
IntegerType,
FunctionType,
ArrayType,
PointerType,
VectorType,
VoidType,
LabelType,
};
TypeTag type_tag;
Type(TypeTag type_tag) : type_tag(type_tag) {}
virtual ~Type() = default;
virtual std::string to_string() {
switch (type_tag) {
case TypeTag::IntegerType: return "IntegerType";
case TypeTag::FunctionType: return "FunctionType";
case TypeTag::ArrayType: return "ArrayType";
case TypeTag::PointerType: return "PointerType";
case TypeTag::VectorType: return "VectorType";
case TypeTag::VoidType: return "VoidType";
case TypeTag::LabelType: return "LabelType";
}
}
template <typename TT>
static bool isType(std::shared_ptr<Type> ptr) {
if (ptr) {
return dynamic_cast<TT *>(ptr.get()) != nullptr;
}
else {
return false;
}
}
template <typename TT>
static std::shared_ptr<TT> asType(std::shared_ptr<Type> ptr) {
return std::dynamic_pointer_cast<TT>(ptr);
}
virtual std::string to_IR_string() = 0;
};
class IntegerType : public Type {
public:
enum class IntTypes { I32, I1 };
IntTypes int_type = IntTypes::I32;
IntegerType(IntTypes int_type = IntTypes::I32) : Type(TypeTag::IntegerType), int_type(int_type) {}
bool isI32() {
return int_type == IntTypes::I32;
}
bool isI1() {
return int_type == IntTypes::I1;
}
static bool isIntegerType(TypePtr_t type) {
return (type->type_tag == Type::TypeTag::IntegerType);
}
static bool isIntegerTypeI32(TypePtr_t type) {
return isIntegerType(type) && std::dynamic_pointer_cast<IntegerType>(type)->isI32();
}
static bool isIntegerTypeI1(TypePtr_t &type) {
return isIntegerType(type) && std::dynamic_pointer_cast<IntegerType>(type)->isI1();
}
virtual std::string to_IR_string() override {
if (isI1())
return "i1";
else
return "i32";
}
};
class VoidType : public Type {
public:
VoidType() : Type(TypeTag::VoidType) {}
virtual std::string to_IR_string() override {
return "void";
}
};
class LabelType : public Type {
public:
LabelType() : Type(TypeTag::LabelType) {}
virtual std::string to_IR_string() override {
panic("Cannot generate LabelType");
}
};
class TypeHelper {
public:
inline static TypePtr_t TYPE_I32 = std::make_shared<IntegerType>();
inline static TypePtr_t TYPE_I1 = std::make_shared<IntegerType>(IntegerType::IntTypes::I1);
inline static TypePtr_t TYPE_LABEL = std::make_shared<LabelType>();
inline static TypePtr_t TYPE_VOID = std::make_shared<VoidType>();
};
class ArrayType : public Type {
public:
TypePtr_t elem_type = TypeHelper::TYPE_I32;
int elem_count = 0; // current dim size
int type_size = 0; // = dim_size * size(elem_type)
ArrayType() : Type(TypeTag::ArrayType) {}
ArrayType(TypePtr_t element_type, int element_count)
: Type(TypeTag::ArrayType), elem_type(element_type), elem_count(element_count) {}
static std::shared_ptr<ArrayType> build_from_list(const std::vector<int> &dim_list) {
TypePtr_t array_type = TypeHelper::TYPE_I32;
sysy_assert(dim_list.size() != 0);
for (auto itr = dim_list.rbegin(); itr != dim_list.rend(); ++itr) {
array_type = std::make_shared<ArrayType>(array_type, *itr);
}
return std::dynamic_pointer_cast<ArrayType>(array_type);
}
virtual std::string to_string() override {
return "Array[" + std::to_string(elem_count) + " x " + elem_type->to_string() + "]";
}
virtual std::string to_IR_string() override {
return "[" + std::to_string(elem_count) + " x " + elem_type->to_IR_string() + "]";
}
};
class PointerType : public Type {
public:
TypePtr_t pointed_type = TypeHelper::TYPE_I32;
PointerType(TypePtr_t pointed_type) : Type(TypeTag::PointerType), pointed_type(pointed_type) {}
static auto make_shared(TypePtr_t pointed_type) {
return std::make_shared<PointerType>(pointed_type);
}
virtual std::string to_string() override {
return "Pointer->" + pointed_type->to_string();
}
virtual std::string to_IR_string() override {
return pointed_type->to_IR_string() + "*";
}
};
class FunctionType : public Type {
public:
TypePtr_t return_type = TypeHelper::TYPE_I32;
std::vector<TypePtr_t> params_type;
FunctionType(TypePtr_t return_type) : Type(TypeTag::FunctionType), return_type(return_type) {}
FunctionType(TypePtr_t return_type, const std::vector<TypePtr_t> &params_type)
: Type(TypeTag::FunctionType), return_type(return_type), params_type(params_type) {}
virtual std::string to_IR_string() override {
panic("Cannot generate FunctionType");
}
};
} // namespace CompSysY