Skip to content

Update reflection on 4.0 to match code in master #9242

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion include/swift/ABI/MetadataValues.h
Original file line number Diff line number Diff line change
Expand Up @@ -410,8 +410,8 @@ class ExistentialTypeFlags {
};
int_type Data;

constexpr ExistentialTypeFlags(int_type Data) : Data(Data) {}
public:
constexpr ExistentialTypeFlags(int_type Data) : Data(Data) {}
constexpr ExistentialTypeFlags() : Data(0) {}
constexpr ExistentialTypeFlags withNumWitnessTables(unsigned numTables) const {
return ExistentialTypeFlags((Data & ~NumWitnessTablesMask) | numTables);
Expand Down
11 changes: 10 additions & 1 deletion include/swift/Reflection/Records.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

#include "swift/Basic/RelativePointer.h"

const uint16_t SWIFT_REFLECTION_METADATA_VERSION = 2; // use new mangling
const uint16_t SWIFT_REFLECTION_METADATA_VERSION = 3; // superclass field

namespace swift {
namespace reflection {
Expand Down Expand Up @@ -145,6 +145,7 @@ class FieldDescriptor {
}

const RelativeDirectPointer<const char> MangledTypeName;
const RelativeDirectPointer<const char> Superclass;

public:
FieldDescriptor() = delete;
Expand Down Expand Up @@ -190,6 +191,14 @@ class FieldDescriptor {
std::string getMangledTypeName() const {
return MangledTypeName.get();
}

bool hasSuperclass() const {
return Superclass;
}

std::string getSuperclass() const {
return Superclass.get();
}
};

class FieldDescriptorIterator
Expand Down
5 changes: 5 additions & 0 deletions include/swift/Reflection/ReflectionContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,11 @@ class ReflectionContext
// solve the problem.
while (!CaptureTypes.empty()) {
const TypeRef *OrigCaptureTR = CaptureTypes[0];

// If we failed to demangle the capture type, we cannot proceed.
if (OrigCaptureTR == nullptr)
return nullptr;

const TypeRef *SubstCaptureTR = nullptr;

// If we have enough substitutions to make this captured value's
Expand Down
31 changes: 21 additions & 10 deletions include/swift/Reflection/TypeRef.h
Original file line number Diff line number Diff line change
Expand Up @@ -421,28 +421,39 @@ class ProtocolTypeRef final : public TypeRef {
};

class ProtocolCompositionTypeRef final : public TypeRef {
std::vector<const TypeRef *> Protocols;
std::vector<const TypeRef *> Members;
bool HasExplicitAnyObject;

static TypeRefID Profile(const std::vector<const TypeRef *> &Protocols) {
static TypeRefID Profile(const std::vector<const TypeRef *> &Members,
bool HasExplicitAnyObject) {
TypeRefID ID;
for (auto Protocol : Protocols) {
ID.addPointer(Protocol);
ID.addInteger((uint32_t)HasExplicitAnyObject);
for (auto Member : Members) {
ID.addPointer(Member);
}
return ID;
}

public:
ProtocolCompositionTypeRef(std::vector<const TypeRef *> Protocols)
: TypeRef(TypeRefKind::ProtocolComposition), Protocols(Protocols) {}
ProtocolCompositionTypeRef(std::vector<const TypeRef *> Members,
bool HasExplicitAnyObject)
: TypeRef(TypeRefKind::ProtocolComposition),
Members(Members), HasExplicitAnyObject(HasExplicitAnyObject) {}

template <typename Allocator>
static const ProtocolCompositionTypeRef *
create(Allocator &A, std::vector<const TypeRef *> Protocols) {
FIND_OR_CREATE_TYPEREF(A, ProtocolCompositionTypeRef, Protocols);\
create(Allocator &A, std::vector<const TypeRef *> Members,
bool HasExplicitAnyObject) {
FIND_OR_CREATE_TYPEREF(A, ProtocolCompositionTypeRef, Members,
HasExplicitAnyObject);
}

const std::vector<const TypeRef *> &getProtocols() const {
return Protocols;
const std::vector<const TypeRef *> &getMembers() const {
return Members;
}

bool hasExplicitAnyObject() const {
return HasExplicitAnyObject;
}

static bool classof(const TypeRef *TR) {
Expand Down
19 changes: 13 additions & 6 deletions include/swift/Reflection/TypeRefBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ class TypeRefBuilder {
TypeRefBuilder &operator=(const TypeRefBuilder &other) = delete;

private:
Demangle::Demangler Dem;

/// Makes sure dynamically allocated TypeRefs stick around for the life of
/// this TypeRefBuilder and are automatically released.
std::vector<std::unique_ptr<const TypeRef>> TypeRefPool;
Expand Down Expand Up @@ -208,17 +210,22 @@ class TypeRefBuilder {

const ProtocolTypeRef *createProtocolType(const std::string &mangledName,
const std::string &moduleName,
const std::string &privateDiscriminator,
const std::string &name) {
return ProtocolTypeRef::create(*this, mangledName);
}

const ProtocolCompositionTypeRef *
createProtocolCompositionType(const std::vector<const TypeRef*> &protocols) {
for (auto protocol : protocols) {
if (!isa<ProtocolTypeRef>(protocol))
createProtocolCompositionType(const std::vector<const TypeRef*> &members,
bool hasExplicitAnyObject) {
for (auto member : members) {
if (!isa<ProtocolTypeRef>(member) &&
!isa<NominalTypeRef>(member) &&
!isa<BoundGenericTypeRef>(member))
return nullptr;
}
return ProtocolCompositionTypeRef::create(*this, protocols);
return ProtocolCompositionTypeRef::create(*this, members,
hasExplicitAnyObject);
}

const ExistentialMetatypeTypeRef *
Expand Down Expand Up @@ -314,8 +321,8 @@ class TypeRefBuilder {
const FieldDescriptor *getFieldTypeInfo(const TypeRef *TR);

/// Get the parsed and substituted field types for a nominal type.
std::vector<FieldTypeInfo>
getFieldTypeRefs(const TypeRef *TR, const FieldDescriptor *FD);
bool getFieldTypeRefs(const TypeRef *TR, const FieldDescriptor *FD,
std::vector<FieldTypeInfo> &Fields);

/// Get the primitive type lowering for a builtin type.
const BuiltinTypeDescriptor *getBuiltinTypeInfo(const TypeRef *TR);
Expand Down
83 changes: 76 additions & 7 deletions include/swift/Remote/MetadataReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,12 +133,55 @@ class TypeDecoder {
}
if (protocols.size() == 1)
return protocols.front();
else
return Builder.createProtocolCompositionType(protocols);
return Builder.createProtocolCompositionType(
protocols,
/*hasExplicitAnyObject=*/false);
}
case NodeKind::ProtocolListWithAnyObject: {
std::vector<BuiltType> protocols;
auto ProtocolList = Node->getChild(0);
auto TypeList = ProtocolList->getChild(0);
for (auto componentType : *TypeList) {
if (auto protocol = decodeMangledType(componentType))
protocols.push_back(protocol);
else
return BuiltType();
}
return Builder.createProtocolCompositionType(
protocols,
/*hasExplicitAnyObject=*/true);
}
case NodeKind::ProtocolListWithClass: {
std::vector<BuiltType> members;
auto ProtocolList = Node->getChild(0);
auto TypeList = ProtocolList->getChild(0);
for (auto componentType : *TypeList) {
if (auto protocol = decodeMangledType(componentType))
members.push_back(protocol);
else
return BuiltType();
}

auto SuperclassNode = Node->getChild(1);
if (auto superclass = decodeMangledType(SuperclassNode))
members.push_back(superclass);

return Builder.createProtocolCompositionType(
members,
/*hasExplicitAnyObject=*/true);
}
case NodeKind::Protocol: {
auto moduleName = Node->getChild(0)->getText();
auto name = Node->getChild(1)->getText();
auto nameNode = Node->getChild(1);
std::string privateDiscriminator, name;
if (nameNode->getKind() == NodeKind::PrivateDeclName) {
privateDiscriminator = nameNode->getChild(0)->getText();
name = nameNode->getChild(1)->getText();
} else if (nameNode->getKind() == NodeKind::Identifier) {
name = Node->getChild(1)->getText();
} else {
return BuiltType();
}

// Consistent handling of protocols and protocol compositions
Demangle::Demangler Dem;
Expand All @@ -150,7 +193,8 @@ class TypeDecoder {
protocolList->addChild(typeList, Dem);

auto mangledName = Demangle::mangleNode(protocolList);
return Builder.createProtocolType(mangledName, moduleName, name);
return Builder.createProtocolType(mangledName, moduleName,
privateDiscriminator, name);
}
case NodeKind::DependentGenericParamType: {
auto depth = Node->getChild(0)->getIndex();
Expand Down Expand Up @@ -724,7 +768,20 @@ class MetadataReader {
}
case MetadataKind::Existential: {
auto Exist = cast<TargetExistentialTypeMetadata<Runtime>>(Meta);
std::vector<BuiltType> Protocols;
std::vector<BuiltType> Members;
bool HasExplicitAnyObject = false;

if (Exist->Flags.hasSuperclassConstraint()) {
// The superclass is stored after the list of protocols.
auto SuperclassType = readTypeFromMetadata(
Exist->Protocols[Exist->Protocols.NumProtocols]);
if (!SuperclassType) return BuiltType();
Members.push_back(SuperclassType);
}

if (Exist->isClassBounded())
HasExplicitAnyObject = true;

for (size_t i = 0; i < Exist->Protocols.NumProtocols; ++i) {
auto ProtocolAddress = Exist->Protocols[i];
auto ProtocolDescriptor = readProtocolDescriptor(ProtocolAddress);
Expand All @@ -741,9 +798,10 @@ class MetadataReader {
if (!Protocol)
return BuiltType();

Protocols.push_back(Protocol);
Members.push_back(Protocol);
}
auto BuiltExist = Builder.createProtocolCompositionType(Protocols);
auto BuiltExist = Builder.createProtocolCompositionType(
Members, HasExplicitAnyObject);
TypeCache[MetadataAddress] = BuiltExist;
return BuiltExist;
}
Expand Down Expand Up @@ -1061,6 +1119,14 @@ class MetadataReader {
case MetadataKind::ErrorObject:
return _readMetadata<TargetEnumMetadata>(address);
case MetadataKind::Existential: {
StoredPointer flagsAddress = address +
sizeof(StoredPointer);

StoredPointer flags;
if (!Reader->readInteger(RemoteAddress(flagsAddress),
&flags))
return nullptr;

StoredPointer numProtocolsAddress = address +
TargetExistentialTypeMetadata<Runtime>::OffsetToNumProtocols;
StoredPointer numProtocols;
Expand All @@ -1076,6 +1142,9 @@ class MetadataReader {
+ numProtocols *
sizeof(ConstTargetMetadataPointer<Runtime, TargetProtocolDescriptor>);

if (ExistentialTypeFlags(flags).hasSuperclassConstraint())
totalSize += sizeof(StoredPointer);

return _readMetadata(address, totalSize);
}
case MetadataKind::ExistentialMetatype:
Expand Down
24 changes: 16 additions & 8 deletions lib/Demangling/NodePrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -278,8 +278,10 @@ class NodePrinter {
case Node::Kind::ProtocolList:
return Node->getChild(0)->getNumChildren() <= 1;

case Node::Kind::ProtocolListWithClass:
case Node::Kind::ProtocolListWithAnyObject:
return Node->getChild(0)->getChild(0)->getNumChildren() == 0;

case Node::Kind::ProtocolListWithClass:
case Node::Kind::Allocator:
case Node::Kind::ArgumentTuple:
case Node::Kind::AssociatedTypeMetadataAccessor:
Expand Down Expand Up @@ -628,7 +630,8 @@ class NodePrinter {
static bool isExistentialType(NodePointer node) {
return (node->getKind() == Node::Kind::ExistentialMetatype ||
node->getKind() == Node::Kind::ProtocolList ||
node->getKind() == Node::Kind::ProtocolListWithClass);
node->getKind() == Node::Kind::ProtocolListWithClass ||
node->getKind() == Node::Kind::ProtocolListWithAnyObject);
}

/// Print the relevant parameters and return the new index.
Expand Down Expand Up @@ -1362,7 +1365,10 @@ NodePointer NodePrinter::print(NodePointer Node, bool asPrefixContext) {
NodePointer superclass = Node->getChild(1);
print(superclass);
Printer << " & ";
printChildren(protocols, " & ");
if (protocols->getNumChildren() < 1)
return nullptr;
NodePointer type_list = protocols->getChild(0);
printChildren(type_list, " & ");
return nullptr;
}
case Node::Kind::ProtocolListWithAnyObject: {
Expand All @@ -1371,12 +1377,14 @@ NodePointer NodePrinter::print(NodePointer Node, bool asPrefixContext) {
NodePointer protocols = Node->getChild(0);
if (protocols->getNumChildren() < 1)
return nullptr;
if (protocols->getChild(0)->getNumChildren() == 0) {
Printer << "AnyObject";
} else {
printChildren(protocols->getChild(0), " & ");
Printer << " & AnyObject";
NodePointer type_list = protocols->getChild(0);
if (type_list->getNumChildren() > 0) {
printChildren(type_list, " & ");
Printer << " & ";
}
if (Options.QualifyEntities)
Printer << "Swift.";
Printer << "AnyObject";
return nullptr;
}
case Node::Kind::AssociatedType:
Expand Down
Loading