| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // Copyright (c) 2021-2025 ChilliBits. All rights reserved. | ||
| 2 | |||
| 3 | #pragma once | ||
| 4 | |||
| 5 | #include <string> | ||
| 6 | #include <vector> | ||
| 7 | |||
| 8 | #include <llvm/IR/Type.h> | ||
| 9 | |||
| 10 | #include <symboltablebuilder/TypeQualifiers.h> | ||
| 11 | |||
| 12 | namespace spice::compiler { | ||
| 13 | |||
| 14 | // Forward declarations | ||
| 15 | class SourceFile; | ||
| 16 | class Type; | ||
| 17 | class ASTNode; | ||
| 18 | class Scope; | ||
| 19 | class Struct; | ||
| 20 | class Interface; | ||
| 21 | class GenericType; | ||
| 22 | class QualType; | ||
| 23 | class SymbolTableEntry; | ||
| 24 | enum SuperType : uint8_t; | ||
| 25 | |||
| 26 | // Constants | ||
| 27 | constexpr const char *const STROBJ_NAME = "String"; | ||
| 28 | constexpr const char *const RESULTOBJ_NAME = "Result"; | ||
| 29 | constexpr const char *const ERROBJ_NAME = "Error"; | ||
| 30 | constexpr const char *const TIOBJ_NAME = "TypeInfo"; | ||
| 31 | constexpr const char *const IITERATOR_NAME = "IIterator"; | ||
| 32 | constexpr const char *const ARRAY_ITERATOR_NAME = "ArrayIterator"; | ||
| 33 | static constexpr const char *const RESERVED_TYPE_NAMES[] = { | ||
| 34 | STROBJ_NAME, RESULTOBJ_NAME, ERROBJ_NAME, TIOBJ_NAME, IITERATOR_NAME, ARRAY_ITERATOR_NAME, | ||
| 35 | }; | ||
| 36 | static constexpr uint64_t TYPE_ID_ITERATOR_INTERFACE = 255; | ||
| 37 | static constexpr uint64_t TYPE_ID_ITERABLE_INTERFACE = 256; | ||
| 38 | |||
| 39 | // Typedefs | ||
| 40 | using QualTypeList = std::vector<QualType>; | ||
| 41 | |||
| 42 | class QualType { | ||
| 43 | public: | ||
| 44 | // Constructors | ||
| 45 | 118901 | QualType() = default; | |
| 46 | explicit QualType(SuperType superType); | ||
| 47 | QualType(SuperType superType, const std::string &subType); | ||
| 48 | QualType(const Type *type, TypeQualifiers qualifiers); | ||
| 49 | |||
| 50 | // Getters and setters on type | ||
| 51 | 915704 | [[nodiscard]] const Type *getType() const { return type; } | |
| 52 | |||
| 53 | // Getters on type parts | ||
| 54 | [[nodiscard]] SuperType getSuperType() const; | ||
| 55 | [[nodiscard]] const std::string &getSubType() const; | ||
| 56 | [[nodiscard]] unsigned int getArraySize() const; | ||
| 57 | [[nodiscard]] Scope *getBodyScope() const; | ||
| 58 | [[nodiscard]] const QualType &getFunctionReturnType() const; | ||
| 59 | [[nodiscard]] QualTypeList getFunctionParamTypes() const; | ||
| 60 | [[nodiscard]] const QualTypeList &getFunctionParamAndReturnTypes() const; | ||
| 61 | [[nodiscard]] bool hasLambdaCaptures() const; | ||
| 62 | [[nodiscard]] const QualTypeList &getTemplateTypes() const; | ||
| 63 | [[nodiscard]] Struct *getStruct(const ASTNode *node, const QualTypeList &templateTypes) const; | ||
| 64 | [[nodiscard]] Struct *getStruct(const ASTNode *node) const; | ||
| 65 | [[nodiscard]] Struct *getStructAndAdjustType(const ASTNode *node, const QualTypeList &templateTypes); | ||
| 66 | [[nodiscard]] Struct *getStructAndAdjustType(const ASTNode *node); | ||
| 67 | [[nodiscard]] Interface *getInterface(const ASTNode *node, const QualTypeList &templateTypes) const; | ||
| 68 | [[nodiscard]] Interface *getInterface(const ASTNode *node) const; | ||
| 69 | |||
| 70 | // Queries on the type | ||
| 71 | [[nodiscard]] bool is(SuperType superType) const; | ||
| 72 | [[nodiscard]] bool isOneOf(const std::initializer_list<SuperType> &superTypes) const; | ||
| 73 | [[nodiscard]] bool isBase(SuperType superType) const; | ||
| 74 | [[nodiscard]] bool isPrimitive() const; | ||
| 75 | [[nodiscard]] bool isExtendedPrimitive() const; | ||
| 76 | [[nodiscard]] bool isPtr() const; | ||
| 77 | [[nodiscard]] bool isPtrTo(SuperType superType) const; | ||
| 78 | [[nodiscard]] bool isRef() const; | ||
| 79 | [[nodiscard]] bool isRefTo(SuperType superType) const; | ||
| 80 | [[nodiscard]] bool isArray() const; | ||
| 81 | [[nodiscard]] bool isArrayOf(SuperType superType) const; | ||
| 82 | [[nodiscard]] bool isConstRef() const; | ||
| 83 | [[nodiscard]] bool isIterator(const ASTNode *node) const; | ||
| 84 | [[nodiscard]] bool isIterable(const ASTNode *node) const; | ||
| 85 | [[nodiscard]] bool isStringObj() const; | ||
| 86 | [[nodiscard]] bool isErrorObj() const; | ||
| 87 | [[nodiscard]] bool hasAnyGenericParts() const; | ||
| 88 | |||
| 89 | // Complex queries on the type | ||
| 90 | [[nodiscard]] bool isTriviallyCopyable(const ASTNode *node) const; | ||
| 91 | [[nodiscard]] bool isTriviallyDestructible(const ASTNode *node) const; | ||
| 92 | [[nodiscard]] bool doesImplement(const QualType &implementedInterfaceType, const ASTNode *node) const; | ||
| 93 | [[nodiscard]] bool canBind(const QualType &inputType, bool isTemporary) const; | ||
| 94 | [[nodiscard]] bool matches(const QualType &otherType, bool ignoreArraySize, bool ignoreQualifiers, bool allowConstify) const; | ||
| 95 | [[nodiscard]] bool matchesInterfaceImplementedByStruct(const QualType &structType) const; | ||
| 96 | [[nodiscard]] bool isSameContainerTypeAs(const QualType &other) const; | ||
| 97 | [[nodiscard]] bool isSelfReferencingStructType(const QualType *typeToCompareWith = nullptr) const; | ||
| 98 | [[nodiscard]] bool isCoveredByGenericTypeList(std::vector<GenericType> &genericTypeList) const; | ||
| 99 | [[nodiscard]] bool needsDeAllocation() const; | ||
| 100 | |||
| 101 | // Serialization | ||
| 102 | void getName(std::stringstream &name, bool withSize = false, bool ignorePublic = false) const; | ||
| 103 | [[nodiscard]] std::string getName(bool withSize = false, bool ignorePublic = false) const; | ||
| 104 | |||
| 105 | // LLVM helpers | ||
| 106 | [[nodiscard]] llvm::Type *toLLVMType(SourceFile *sourceFile) const; | ||
| 107 | |||
| 108 | // Get new type, based on this one | ||
| 109 | [[nodiscard]] QualType toPtr(const ASTNode *node) const; | ||
| 110 | [[nodiscard]] QualType toRef(const ASTNode *node) const; | ||
| 111 | [[nodiscard]] QualType toConstRef(const ASTNode *node) const; | ||
| 112 | [[nodiscard]] QualType toArr(const ASTNode *node, size_t size, bool skipDynCheck = false) const; | ||
| 113 | [[nodiscard]] QualType toNonConst() const; | ||
| 114 | [[nodiscard]] QualType getContained() const; | ||
| 115 | [[nodiscard]] QualType getBase() const; | ||
| 116 | [[nodiscard]] QualType getAliased(const SymbolTableEntry *aliasEntry) const; | ||
| 117 | [[nodiscard]] QualType removeReferenceWrapper() const; | ||
| 118 | [[nodiscard]] QualType autoDeReference() const; | ||
| 119 | [[nodiscard]] QualType replaceBaseType(const QualType &newBaseType) const; | ||
| 120 | [[nodiscard]] QualType getWithLambdaCaptures(bool enabled = true) const; | ||
| 121 | [[nodiscard]] QualType getWithBodyScope(Scope *bodyScope) const; | ||
| 122 | [[nodiscard]] QualType getWithTemplateTypes(const QualTypeList &templateTypes) const; | ||
| 123 | [[nodiscard]] QualType getWithBaseTemplateTypes(const QualTypeList &templateTypes) const; | ||
| 124 | [[nodiscard]] QualType getWithFunctionParamAndReturnTypes(const QualTypeList ¶mAndReturnTypes) const; | ||
| 125 | [[nodiscard]] QualType getWithFunctionParamAndReturnTypes(const QualType &returnType, const QualTypeList ¶mTypes) const; | ||
| 126 | |||
| 127 | // Getters and setters on qualifiers | ||
| 128 | 329061 | [[nodiscard]] TypeQualifiers &getQualifiers() { return qualifiers; } | |
| 129 | 822454 | [[nodiscard]] const TypeQualifiers &getQualifiers() const { return qualifiers; } | |
| 130 | 34108 | void setQualifiers(TypeQualifiers newQualifiers) { qualifiers = newQualifiers; } | |
| 131 | |||
| 132 | // Getters and setters on qualifier parts | ||
| 133 | [[nodiscard]] bool isConst() const; | ||
| 134 | [[nodiscard]] bool isSigned() const; | ||
| 135 | [[nodiscard]] bool isUnsigned() const; | ||
| 136 | [[nodiscard]] bool isInline() const; | ||
| 137 | [[nodiscard]] bool isPublic() const; | ||
| 138 | [[nodiscard]] bool isHeap() const; | ||
| 139 | [[nodiscard]] bool isComposition() const; | ||
| 140 | void makeConst(bool isConst = true); | ||
| 141 | void makeUnsigned(bool isUnsigned = true); | ||
| 142 | void makePublic(bool isPublic = true); | ||
| 143 | void makeHeap(bool isHeap = true); | ||
| 144 | |||
| 145 | // Overloaded operators | ||
| 146 | friend bool operator==(const QualType &lhs, const QualType &rhs); | ||
| 147 | friend bool operator!=(const QualType &lhs, const QualType &rhs); | ||
| 148 | |||
| 149 | // Public static methods | ||
| 150 | static void unwrapBoth(QualType &typeA, QualType &typeB); | ||
| 151 | |||
| 152 | private: | ||
| 153 | // Private members | ||
| 154 | const Type *type = nullptr; | ||
| 155 | TypeQualifiers qualifiers; | ||
| 156 | }; | ||
| 157 | |||
| 158 | // Make sure we have no unexpected increases in memory consumption | ||
| 159 | static_assert(sizeof(QualType) == 16); | ||
| 160 | |||
| 161 | } // namespace spice::compiler | ||
| 162 |