//===--- Records.h - Swift Type Reflection Records --------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information // See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // //===----------------------------------------------------------------------===// // // Implements the structures of type reflection records. // //===----------------------------------------------------------------------===// #ifndef SWIFT_REFLECTION_RECORDS_H #define SWIFT_REFLECTION_RECORDS_H #include "swift/Basic/RelativePointer.h" namespace swift { namespace reflection { // Field records describe the type of a single stored property or case member // of a class, struct or enum. class FieldRecordFlags { using int_type = uint32_t; enum : int_type { IsObjC = 0x00000001, }; int_type Data; public: bool isObjC() const { return Data & IsObjC; } void setIsObjC(bool ObjC) { if (ObjC) Data |= IsObjC; else Data &= ~IsObjC; } int_type getRawValue() const { return Data; } }; class FieldRecord { const FieldRecordFlags Flags; const RelativeDirectPointer MangledTypeName; const RelativeDirectPointer FieldName; public: FieldRecord() = delete; bool hasMangledTypeName() const { return MangledTypeName; } std::string getMangledTypeName() const { return MangledTypeName.get(); } std::string getFieldName() const { if (FieldName) return FieldName.get(); return ""; } bool isObjC() const { return Flags.isObjC(); } }; struct FieldRecordIterator { const FieldRecord *Cur; const FieldRecord * const End; FieldRecordIterator(const FieldRecord *Cur, const FieldRecord * const End) : Cur(Cur), End(End) {} const FieldRecord &operator*() const { return *Cur; } FieldRecordIterator &operator++() { ++Cur; return *this; } bool operator==(const FieldRecordIterator &other) const { return Cur == other.Cur && End == other.End; } bool operator!=(const FieldRecordIterator &other) const { return !(*this == other); } }; enum class FieldDescriptorKind : uint16_t { Struct, Class, Enum, Protocol, ClassProtocol, ObjCProtocol, }; // Field descriptors contain a collection of field records for a single // class, struct or enum declaration. class FieldDescriptor { const FieldRecord *getFieldRecordBuffer() const { return reinterpret_cast(this + 1); } const RelativeDirectPointer MangledTypeName; public: FieldDescriptor() = delete; const FieldDescriptorKind Kind; const uint16_t FieldRecordSize; const uint32_t NumFields; using const_iterator = FieldRecordIterator; const_iterator begin() const { auto Begin = getFieldRecordBuffer(); auto End = Begin + NumFields; return const_iterator { Begin, End }; } const_iterator end() const { auto Begin = getFieldRecordBuffer(); auto End = Begin + NumFields; return const_iterator { End, End }; } bool hasMangledTypeName() const { return MangledTypeName; } std::string getMangledTypeName() const { return MangledTypeName.get(); } }; class FieldDescriptorIterator : public std::iterator { public: const void *Cur; const void * const End; FieldDescriptorIterator(const void *Cur, const void * const End) : Cur(Cur), End(End) {} const FieldDescriptor &operator*() const { return *reinterpret_cast(Cur); } FieldDescriptorIterator &operator++() { const auto &FR = this->operator*(); const void *Next = reinterpret_cast(Cur) + sizeof(FieldDescriptor) + FR.NumFields * FR.FieldRecordSize; Cur = Next; return *this; } bool operator==(FieldDescriptorIterator const &other) const { return Cur == other.Cur && End == other.End; } bool operator!=(FieldDescriptorIterator const &other) const { return !(*this == other); } }; // Associated type records describe the mapping from an associated // type to the type witness of a conformance. class AssociatedTypeRecord { const RelativeDirectPointer Name; const RelativeDirectPointer SubstitutedTypeName; public: std::string getName() const { return Name.get(); } std::string getMangledSubstitutedTypeName() const { return SubstitutedTypeName.get(); } }; struct AssociatedTypeRecordIterator { const AssociatedTypeRecord *Cur; const AssociatedTypeRecord * const End; AssociatedTypeRecordIterator() : Cur(nullptr), End(nullptr) {} AssociatedTypeRecordIterator(const AssociatedTypeRecord *Cur, const AssociatedTypeRecord * const End) : Cur(Cur), End(End) {} const AssociatedTypeRecord &operator*() const { return *Cur; } AssociatedTypeRecordIterator &operator++() { ++Cur; return *this; } AssociatedTypeRecordIterator operator=(const AssociatedTypeRecordIterator &Other) { return { Other.Cur, Other.End }; } bool operator==(const AssociatedTypeRecordIterator &other) const { return Cur == other.Cur && End == other.End; } bool operator!=(const AssociatedTypeRecordIterator &other) const { return !(*this == other); } operator bool() const { return Cur && End; } }; // An associated type descriptor contains a collection of associated // type records for a conformance. struct AssociatedTypeDescriptor { const RelativeDirectPointer ConformingTypeName; const RelativeDirectPointer ProtocolTypeName; uint32_t NumAssociatedTypes; uint32_t AssociatedTypeRecordSize; const AssociatedTypeRecord *getAssociatedTypeRecordBuffer() const { return reinterpret_cast(this + 1); } public: using const_iterator = AssociatedTypeRecordIterator; const_iterator begin() const { auto Begin = getAssociatedTypeRecordBuffer(); auto End = Begin + NumAssociatedTypes; return const_iterator { Begin, End }; } const_iterator end() const { auto Begin = getAssociatedTypeRecordBuffer(); auto End = Begin + NumAssociatedTypes; return const_iterator { End, End }; } std::string getMangledProtocolTypeName() const { return ProtocolTypeName.get(); } std::string getMangledConformingTypeName() const { return ConformingTypeName.get(); } }; class AssociatedTypeIterator : public std::iterator { public: const void *Cur; const void * const End; AssociatedTypeIterator(const void *Cur, const void * const End) : Cur(Cur), End(End) {} const AssociatedTypeDescriptor &operator*() const { return *reinterpret_cast(Cur); } AssociatedTypeIterator &operator++() { const auto &ATR = this->operator*(); size_t Size = sizeof(AssociatedTypeDescriptor) + ATR.NumAssociatedTypes * ATR.AssociatedTypeRecordSize; const void *Next = reinterpret_cast(Cur) + Size; Cur = Next; return *this; } bool operator==(AssociatedTypeIterator const &other) const { return Cur == other.Cur && End == other.End; } bool operator!=(AssociatedTypeIterator const &other) const { return !(*this == other); } }; // Builtin type records describe basic layout information about // any builtin types referenced from the other sections. class BuiltinTypeDescriptor { const RelativeDirectPointer TypeName; public: uint32_t Size; uint32_t Alignment; uint32_t Stride; uint32_t NumExtraInhabitants; bool hasMangledTypeName() const { return TypeName; } std::string getMangledTypeName() const { return TypeName.get(); } }; class BuiltinTypeDescriptorIterator : public std::iterator { public: const void *Cur; const void * const End; BuiltinTypeDescriptorIterator(const void *Cur, const void * const End) : Cur(Cur), End(End) {} const BuiltinTypeDescriptor &operator*() const { return *reinterpret_cast(Cur); } BuiltinTypeDescriptorIterator &operator++() { const void *Next = reinterpret_cast(Cur) + sizeof(BuiltinTypeDescriptor); Cur = Next; return *this; } bool operator==(BuiltinTypeDescriptorIterator const &other) const { return Cur == other.Cur && End == other.End; } bool operator!=(BuiltinTypeDescriptorIterator const &other) const { return !(*this == other); } }; } // end namespace reflection } // end namespace swift #endif // SWIFT_REFLECTION_RECORDS_H