#ifndef QLOW_SEM_TYPE_H #define QLOW_SEM_TYPE_H #include #include #include #include namespace llvm { class Value; class Type; class LLVMContext; } namespace qlow::sem { struct SemanticObject; class Type; class NativeType; class ClassType; class ArrayType; // forward declarations to other files struct Class; class TypeScope; class Context; } struct qlow::sem::SemanticObject { Context& context; inline SemanticObject(Context& context) : context{ context } {} virtual ~SemanticObject(void); /** * @brief converts the object to a readable string for debugging purposes. */ virtual std::string toString(void) const; }; class qlow::sem::Type { friend class Context; protected: std::unique_ptr typeScope; llvm::Type* llvmType; Type(void); public: virtual ~Type(void); Type(const Type& other) = delete; Type(Type&& other) = delete; void operator = (const Type& other) = delete; Type& operator = (Type&& other) = delete; virtual std::string asString(void) const = 0; virtual std::string asIdentifier(void) const = 0; virtual size_t hash(void) const = 0; bool operator == (const Type& other) const; inline bool operator != (const Type& other) const { return !this->operator==(other); } virtual bool equals(const Type& other) const = 0; /** * @brief return the class of this type if it is a class type, * nullptr otherwise. * @post ensures that if this->getKind() == Kind::CLASS, * it will not return a nullptr */ virtual Class* getClass(void) const; /** * @brief returns the type scope of this type */ inline TypeScope& getTypeScope(void) const { return *typeScope; } /** * @brief sets the type scope of this type */ void setTypeScope(std::unique_ptr scope); //virtual void setLlvmType(llvm::Type* type); virtual llvm::Type* getLlvmType(llvm::LLVMContext&) const; virtual void createLlvmTypeDecl(llvm::LLVMContext&) = 0; virtual bool isClassType(void) const; virtual bool isNativeType(void) const; virtual bool isArrayType(void) const; virtual bool isVoid(void) const; }; class qlow::sem::NativeType : public Type { friend class Context; public: enum class NType { VOID, INTEGER, BOOLEAN, }; protected: NType type; inline NativeType(NType type) : type{ type } { } public: virtual bool equals(const Type& other) const override; virtual bool isNativeType(void) const override; virtual bool isVoid(void) const override; virtual std::string asString(void) const override; virtual std::string asIdentifier(void) const override; virtual size_t hash(void) const override; virtual void createLlvmTypeDecl(llvm::LLVMContext&) override; }; class qlow::sem::ClassType : public Type { friend class Context; protected: Class* type; inline ClassType(Class* type) : type{ type } { } public: virtual bool equals(const Type& other) const override; virtual bool isClassType(void) const override; virtual Class* getClass(void) const override; virtual std::string asString(void) const override; virtual std::string asIdentifier(void) const override; virtual size_t hash(void) const override; virtual void createLlvmTypeDecl(llvm::LLVMContext&) override; }; class qlow::sem::ArrayType : public Type { friend class Context; protected: Type* elementType; inline ArrayType(Type* elementType) : elementType{ elementType } { } public: virtual bool equals(const Type& other) const override; virtual bool isArrayType(void) const override; virtual std::string asString(void) const override; virtual std::string asIdentifier(void) const override; virtual size_t hash(void) const override; virtual void createLlvmTypeDecl(llvm::LLVMContext&) override; }; #endif // QLOW_SEM_TYPE_H