#ifndef CXXFOOZZ_SRC_TYPE_HPP_ #define CXXFOOZZ_SRC_TYPE_HPP_ #include "model.hpp" namespace cxxfoozz { enum class TypeVariant { kPrimitive = 0, kClass, kEnum, kTemplateTypename, kTemplateTypenameSpc, kSTL, }; class Type { public: explicit Type(std::string name, TypeVariant variant); const std::string &GetName() const; TypeVariant GetVariant() const; private: std::string name_; TypeVariant variant_; }; enum class PrimitiveTypeVariant { kVoid, kBoolean, kShort, kCharacter, kInteger, kLong, kLongLong, kFloat, kDouble, kWideCharacter, kNullptrType, }; class PrimitiveType : public Type { public: PrimitiveType( const std::string &name, PrimitiveTypeVariant primitive_type_variant ); static const std::shared_ptr kVoid; static const std::shared_ptr kBoolean; static const std::shared_ptr kShort; static const std::shared_ptr kCharacter; static const std::shared_ptr kInteger; static const std::shared_ptr kLong; static const std::shared_ptr kLongLong; static const std::shared_ptr kFloat; static const std::shared_ptr kDouble; static const std::shared_ptr kWideCharacter; static const std::shared_ptr kNullptrType; static int SizeOf(const std::shared_ptr &t); PrimitiveTypeVariant GetPrimitiveTypeVariant() const; private: PrimitiveTypeVariant primitive_type_variant_; }; class StructType : public Type { // TODO (TRL-9)! StructType() : Type(std::string(), cxxfoozz::TypeVariant::kClass) {} }; enum class STLTypeVariant { kRegContainer = 0, kRegContainerWithSize, kKeyValueContainer, kPair, kTuple, kSmartPointer, kString, }; class STLType : public Type { public: STLType( const std::string &name, STLTypeVariant template_spc_type, std::vector name_aliases ); STLTypeVariant GetSTLTypeVariant() const; static bool IsSTLType(const std::string &name); static bool IsUnhandledSTLType(const std::string &name); static std::shared_ptr IsInstalledSTLType(const std::string &name); int GetTemplateArgumentLength() const; // Regular Containers static const std::shared_ptr kVector; static const std::shared_ptr kDeque; static const std::shared_ptr kForwardList; static const std::shared_ptr kList; static const std::shared_ptr kStack; static const std::shared_ptr kQueue; static const std::shared_ptr kPriorityQueue; static const std::shared_ptr kSet; static const std::shared_ptr kMultiset; static const std::shared_ptr kUnorderedSet; static const std::shared_ptr kUnorderedMultiset; // Key Value Containers static const std::shared_ptr kMap; static const std::shared_ptr kMultimap; static const std::shared_ptr kUnorderedMap; static const std::shared_ptr kUnorderedMultimap; // Special Containers static const std::shared_ptr kArray; static const std::shared_ptr kPair; static const std::shared_ptr kTuple; // Smart Pointers static const std::shared_ptr kSharedPtr; static const std::shared_ptr kUniquePtr; // String static const std::shared_ptr kBasicString; static std::vector> kInstalledSTLTypes; private: STLTypeVariant stl_type_variant_; std::vector name_aliases_; }; class ClassType : public Type { public: explicit ClassType(std::shared_ptr model); static const std::map> &GetKGlobalClassTypes(); const std::shared_ptr &GetModel() const; static std::shared_ptr GetTypeByQualName(const std::string &qual_name); static std::shared_ptr GetTypeByQualNameLifted(const std::string &qual_name); static void Install(const std::vector> &models); private: static std::map> kGlobalClassTypes; std::shared_ptr model_; }; class EnumType : public Type { public: explicit EnumType(std::shared_ptr model); static const std::map> &GetKGlobalEnumTypes(); const std::shared_ptr &GetModel() const; static std::shared_ptr GetTypeByQualName(const std::string &qual_name); static void Install(const std::vector> &models); private: static std::map> kGlobalEnumTypes; std::shared_ptr model_; }; class TemplateTypenameType : public Type { public: explicit TemplateTypenameType(const std::string &name); }; enum class Modifier { kConst = 0, kConstOnPointer, kUnsigned, kPointer, kArray, kReference, // lvalue reference kRValueReference, }; class TypeWithModifier; class TemplateTypeInstantiation; class TemplateTypeInstList { public: explicit TemplateTypeInstList(std::vector inst_types); const std::vector &GetInstantiations() const; std::string ToString() const; bool Equals(const TemplateTypeInstList &other) const; private: std::vector insts_; }; class TemplateTypenameSpcType : public Type { public: TemplateTypenameSpcType( std::shared_ptr target_type, TemplateTypeInstList inst_list ); static const std::shared_ptr &From( const std::shared_ptr &target_type, const TemplateTypeInstList &inst_list ); const std::shared_ptr &GetTargetType() const; const TemplateTypeInstList &GetInstList() const; private: static std::vector> &LookupExistingByTargetType(const std::shared_ptr &target); static std::map, std::vector>> kGlobalExistingSpcTypes; std::shared_ptr target_type_; TemplateTypeInstList inst_list_; }; class TemplateTypeInstMapping { public: TemplateTypeInstMapping(); explicit TemplateTypeInstMapping(std::map inst_mapping); TemplateTypeInstMapping(const TemplateTypeInstMapping &other); const std::map &GetInstMapping() const; const TypeWithModifier &LookupOrResolve( const std::string &template_typename, const std::function &resolver ); TemplateTypeInstList LookupForClass(const std::shared_ptr &class_type_model); TemplateTypeInstList LookupForExecutable(const std::shared_ptr &executable); TemplateTypeInstList LookupFromTemplateTypeParamList(const TemplateTypeParamList &template_type_param_list); TemplateTypeInstMapping &Bind(const TemplateTypeParam &ttp, const TypeWithModifier &type); void ApplyBindings(const std::map &bindings); private: std::map inst_mapping_; }; class TemplateTypeContext { public: TemplateTypeContext(); explicit TemplateTypeContext(const TemplateTypeInstMapping &mapping); TemplateTypeContext(const TemplateTypeContext &other); TemplateTypeInstMapping &GetMapping(); static std::shared_ptr New(); static std::shared_ptr Clone(const std::shared_ptr &ref); const TypeWithModifier &LookupOrResolve(const std::string &template_typename); TemplateTypeContext &Bind(const TemplateTypeParam &ttp, const TypeWithModifier &type); void ApplyBindings(const std::map &bindings); private: TemplateTypeInstMapping mapping_; }; class TWMSpec { public: TWMSpec(); static TWMSpec ByType(const std::shared_ptr &by_type, const std::shared_ptr &tt_ctx); static TWMSpec ByClangType(const clang::QualType &by_clang_type, const std::shared_ptr &tt_ctx); const std::shared_ptr &GetByType() const; void SetByType(const std::shared_ptr &by_type); const bpstd::optional &GetByClangType() const; void SetByClangType(const bpstd::optional &by_clang_type); const std::multiset &GetAdditionalMods() const; void SetAdditionalMods(const std::multiset &additional_mods); const std::shared_ptr &GetTemplateTypeContext() const; void SetTemplateTypeContext(const std::shared_ptr &template_type_context); private: std::shared_ptr by_type_; bpstd::optional by_clang_type_; std::multiset additional_mods_; std::shared_ptr template_type_context_; }; class TypeWithModifier { public: TypeWithModifier(std::shared_ptr type, std::multiset modifiers); TypeWithModifier(const TypeWithModifier &other); static TypeWithModifier FromSpec(const TWMSpec &spec); static TypeWithModifier Bottom(); TypeWithModifier ResolveTemplateType(const std::shared_ptr &tt_ctx) const; TypeWithModifier StripAllModifiers() const; TypeWithModifier WithAdditionalModifiers(const std::multiset &mods) const; TypeWithModifier StripParticularModifiers(const std::multiset &mods) const; bool operator==(const TypeWithModifier &rhs) const; bool operator!=(const TypeWithModifier &rhs) const; const std::shared_ptr &GetType() const; const std::multiset &GetModifiers() const; bool IsVoidType() const; bool IsPrimitiveType() const; bool IsClassType() const; bool IsEnumType() const; bool IsTemplateTypenameType() const; bool IsTemplateTypenameSpcType() const; std::string ToString() const; std::string ToString(const std::shared_ptr &template_type_context) const; std::string GetDefaultVarName() const; bool IsAssignableFrom( const TypeWithModifier &other, const std::shared_ptr &tt_ctx, const std::shared_ptr &itm ) const; bool IsConst() const; bool IsUnsigned() const; bool IsPointer() const; bool IsConstOnPointer() const; bool IsVoidPtr() const; bool IsArray() const; bool IsReference() const; bool IsRValueReference() const; bool IsPointerOrArray() const; bool IsBottomType() const; private: std::shared_ptr type_; std::multiset modifiers_; bool bottom_type_; }; enum class TemplateTypeInstVariant { kType = 0, kIntegral, kNullptr, }; class TemplateTypeInstantiation { public: TemplateTypeInstantiation( bpstd::optional type, const bpstd::optional &integral, TemplateTypeInstVariant variant ); static TemplateTypeInstantiation ForType(const TypeWithModifier &type); static TemplateTypeInstantiation ForIntegral(const int &integral); static TemplateTypeInstantiation ForNullptr(); const TypeWithModifier &GetType() const; int GetIntegral() const; TemplateTypeInstVariant GetVariant() const; bool IsType() const; std::string ToString() const; bool operator==(const TemplateTypeInstantiation &rhs) const; bool operator!=(const TemplateTypeInstantiation &rhs) const; private: bpstd::optional type_; bpstd::optional integral_; TemplateTypeInstVariant variant_; }; } #endif //CXXFOOZZ_SRC_TYPE_HPP_