#ifndef TYPES_H #define TYPES_H #include "builder.h" #include #include namespace types { enum class TypeKind { Fundamental, Function, Pointer, Array, Struct, }; enum FundamentalTypeKind { Int, Bool, Char, Void, /// @brief Mainly used for binop resolution Any, }; class Type { public: TypeKind m_kind; bool m_const; Type(TypeKind kind, bool is_const) : m_kind{ kind }, m_const{ is_const } {} virtual ~Type() = default; virtual std::string formatted() = 0; virtual llvm::Type* codegen(codegen::Builder& builder, codegen::TypeMap& structs) = 0; virtual std::pair> load(codegen::Builder& builder, llvm::Value* ptr, codegen::TypeMap& structs) = 0; virtual std::optional> return_type(); virtual bool is_signed(); virtual uint32_t size() = 0; }; class FundamentalType : public Type { public: FundamentalTypeKind m_ty; FundamentalType(bool is_const, FundamentalTypeKind kind) : Type(TypeKind::Fundamental, is_const), m_ty{ kind } {} virtual ~FundamentalType() override = default; virtual std::string formatted() override; virtual llvm::Type* codegen(codegen::Builder& builder, codegen::TypeMap& structs) override; virtual std::pair> load(codegen::Builder& builder, llvm::Value* ptr, codegen::TypeMap& structs) override; virtual bool is_signed() override; virtual uint32_t size() override; }; class FunctionType : public Type { public: std::shared_ptr m_ret_ty; std::vector> m_param_tys; bool m_vararg; FunctionType(bool is_const, std::shared_ptr ret_ty, std::vector> param_tys, bool vararg) : Type(TypeKind::Function, is_const) , m_ret_ty{ std::move(ret_ty) } , m_param_tys{ std::move(param_tys) } , m_vararg{ vararg } { } virtual ~FunctionType() override = default; virtual std::string formatted() override; virtual llvm::Type* codegen(codegen::Builder& builder, codegen::TypeMap& structs) override; virtual std::pair> load(codegen::Builder& builder, llvm::Value* ptr, codegen::TypeMap& structs) override; virtual std::optional> return_type() override; virtual uint32_t size() override; }; class PointerType : public Type { public: std::shared_ptr m_inner; PointerType(bool is_const, std::shared_ptr inner) : Type(TypeKind::Pointer, is_const), m_inner{ std::move(inner) } { } virtual ~PointerType() override = default; virtual std::string formatted() override; virtual llvm::Type* codegen(codegen::Builder& builder, codegen::TypeMap& structs) override; virtual std::pair> load(codegen::Builder& builder, llvm::Value* ptr, codegen::TypeMap& structs) override; virtual uint32_t size() override; }; class ArrayType : public Type { public: std::shared_ptr m_inner; uint32_t m_size; bool m_raw; ArrayType(std::shared_ptr inner, uint32_t size, bool raw) : Type(TypeKind::Array, true), m_inner{ std::move(inner) }, m_size{ size }, m_raw{ raw } { } virtual ~ArrayType() override = default; virtual std::string formatted() override; virtual llvm::Type* codegen(codegen::Builder& builder, codegen::TypeMap& structs) override; virtual std::pair> load(codegen::Builder& builder, llvm::Value* ptr, codegen::TypeMap& structs) override; virtual uint32_t size() override; }; typedef std::pair> StructField; class StructType : public Type { public: std::optional m_name; std::optional> m_fields; bool m_is_ref; bool m_is_def; uint32_t m_id; StructType(bool is_const, std::optional name, std::optional> fields, bool is_ref, bool is_def, uint32_t id) : Type(TypeKind::Struct, is_const), m_name{ name }, m_fields{ fields }, m_is_ref{ is_ref }, m_is_def{ is_def }, m_id{ id } { } virtual ~StructType() override = default; virtual std::string formatted() override; virtual llvm::Type* codegen(codegen::Builder& builder, codegen::TypeMap& structs) override; virtual std::pair> load(codegen::Builder& builder, llvm::Value* ptr, codegen::TypeMap& structs) override; virtual uint32_t size() override; }; bool types_equal(std::shared_ptr type1, std::shared_ptr type2); } #endif