#ifndef _SYSYF_TYPE_H_ #define _SYSYF_TYPE_H_ #include #include #include "internal_types.h" namespace SysYF { namespace IR { class Module; class IntegerType; class FloatType; class FunctionType; class ArrayType; class PointerType; class Type; class Type : public std::enable_shared_from_this { public: enum TypeID { VoidTyID, // Void LabelTyID, // Labels, e.g., BasicBlock IntegerTyID, // Integers, include 32 bits and 1 bit FloatTyID, // Floats, only 32 bits FunctionTyID, // Functions ArrayTyID, // Arrays PointerTyID, // Pointer }; static Ptr create(TypeID tid, Ptr m); ~Type() = default; TypeID get_type_id() const { return tid_; } bool is_void_type() const { return get_type_id() == VoidTyID; } bool is_label_type() const { return get_type_id() == LabelTyID; } bool is_integer_type() const { return get_type_id() == IntegerTyID; } bool is_float_type() const { return get_type_id() == FloatTyID; } bool is_function_type() const { return get_type_id() == FunctionTyID; } bool is_array_type() const { return get_type_id() == ArrayTyID; } bool is_pointer_type() const { return get_type_id() == PointerTyID; } static bool is_eq_type(Ptr ty1, Ptr ty2); static Ptr get_void_type(Ptr m); static Ptr get_label_type(Ptr m); static Ptr get_int1_type(Ptr m); static Ptr get_int32_type(Ptr m); static Ptr get_float_type(Ptr m); static Ptr get_int32_ptr_type(Ptr m); static Ptr get_float_ptr_type(Ptr m); static Ptr get_pointer_type(Ptr contained); static Ptr get_array_type(Ptr contained, unsigned num_elements); Ptr get_pointer_element_type(); Ptr get_array_element_type(); int get_size(); Ptr get_module(); std::string print(); protected: explicit Type(TypeID tid, Ptr m); void init(TypeID tid, Ptr m) {} private: TypeID tid_; Ptr m_; }; class IntegerType : public Type { public: static Ptr create(unsigned num_bits, Ptr m ); unsigned get_num_bits(); private: explicit IntegerType(unsigned num_bits ,Ptr m); void init(unsigned num_bits ,Ptr m) { Type::init(IntegerTyID, m); } unsigned num_bits_; }; class FloatType : public Type { public: static Ptr create(Ptr m); private: explicit FloatType(Ptr m); void init(Ptr m) { Type::init(FloatTyID, m); } }; class FunctionType : public Type { public: static Ptr create(Ptr result, PtrVec params); static bool is_valid_return_type(Ptr ty); static bool is_valid_argument_type(Ptr ty); unsigned get_num_of_args() const; Ptr get_param_type(unsigned i) const; PtrVec::iterator param_begin() { return args_.begin(); } PtrVec::iterator param_end() { return args_.end(); } Ptr get_return_type() const; private: explicit FunctionType(Ptr result, PtrVec params); void init(Ptr result, PtrVec params) { Type::init(FunctionTyID, nullptr); } Ptr result_; PtrVec args_; }; class ArrayType : public Type { public: static bool is_valid_element_type(Ptr ty); static Ptr get(Ptr contained, unsigned num_elements); static Ptr create(Ptr contained, unsigned num_elements); Ptr get_element_type() const { return contained_; } unsigned get_num_of_elements() const { return num_elements_; } private: explicit ArrayType(Ptr contained, unsigned num_elements); void init(Ptr contained, unsigned num_elements) { Type::init(ArrayTyID, nullptr); } Ptr contained_; // The element type of the array. unsigned num_elements_; // Number of elements in the array. }; class PointerType : public Type { public: Ptr get_element_type() const { return contained_; } static Ptr get(Ptr contained); static Ptr create(Ptr contained); private: explicit PointerType(Ptr contained); void init(Ptr contained) { Type::init(PointerTyID, nullptr); } Ptr contained_; // The element type of the ptr. }; } } #endif // _SYSYF_TYPE_H_