Files
swift-mirror/include/swift/Reflection/Records.h
Slava Pestov 00e0c89b30 IRGen: Emit reflection info for protocols
For now, just enough for lowering.

Perhaps we should have a way to always just get this information
from metadata instead, since protocol metadata is always static
and not instantiated.

This would require the static "object file" interface used by
swift-reflection-dump to take a callback for symbol lookup.
2016-04-25 20:08:48 -07:00

351 lines
8.7 KiB
C++

//===--- 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<const char> MangledTypeName;
const RelativeDirectPointer<const char> 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<const FieldRecord *>(this + 1);
}
const RelativeDirectPointer<const char> 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<std::forward_iterator_tag, FieldDescriptor> {
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<const FieldDescriptor *>(Cur);
}
FieldDescriptorIterator &operator++() {
const auto &FR = this->operator*();
const void *Next = reinterpret_cast<const char *>(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<const char> Name;
const RelativeDirectPointer<const char> 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<const char> ConformingTypeName;
const RelativeDirectPointer<const char> ProtocolTypeName;
uint32_t NumAssociatedTypes;
uint32_t AssociatedTypeRecordSize;
const AssociatedTypeRecord *getAssociatedTypeRecordBuffer() const {
return reinterpret_cast<const AssociatedTypeRecord *>(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<std::forward_iterator_tag, AssociatedTypeDescriptor> {
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<const AssociatedTypeDescriptor *>(Cur);
}
AssociatedTypeIterator &operator++() {
const auto &ATR = this->operator*();
size_t Size = sizeof(AssociatedTypeDescriptor) +
ATR.NumAssociatedTypes * ATR.AssociatedTypeRecordSize;
const void *Next = reinterpret_cast<const char *>(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<const char> 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<std::forward_iterator_tag, BuiltinTypeDescriptor> {
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<const BuiltinTypeDescriptor *>(Cur);
}
BuiltinTypeDescriptorIterator &operator++() {
const void *Next = reinterpret_cast<const char *>(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