Skip to content

Commit e530413

Browse files
author
ematejska
authored
Merge pull request #9242 from slavapestov/reflection-syncup-4.0
Update reflection on 4.0 to match code in master
2 parents c050e38 + 1494564 commit e530413

File tree

19 files changed

+535
-191
lines changed

19 files changed

+535
-191
lines changed

include/swift/ABI/MetadataValues.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,8 +410,8 @@ class ExistentialTypeFlags {
410410
};
411411
int_type Data;
412412

413-
constexpr ExistentialTypeFlags(int_type Data) : Data(Data) {}
414413
public:
414+
constexpr ExistentialTypeFlags(int_type Data) : Data(Data) {}
415415
constexpr ExistentialTypeFlags() : Data(0) {}
416416
constexpr ExistentialTypeFlags withNumWitnessTables(unsigned numTables) const {
417417
return ExistentialTypeFlags((Data & ~NumWitnessTablesMask) | numTables);

include/swift/Reflection/Records.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
#include "swift/Basic/RelativePointer.h"
2121

22-
const uint16_t SWIFT_REFLECTION_METADATA_VERSION = 2; // use new mangling
22+
const uint16_t SWIFT_REFLECTION_METADATA_VERSION = 3; // superclass field
2323

2424
namespace swift {
2525
namespace reflection {
@@ -145,6 +145,7 @@ class FieldDescriptor {
145145
}
146146

147147
const RelativeDirectPointer<const char> MangledTypeName;
148+
const RelativeDirectPointer<const char> Superclass;
148149

149150
public:
150151
FieldDescriptor() = delete;
@@ -190,6 +191,14 @@ class FieldDescriptor {
190191
std::string getMangledTypeName() const {
191192
return MangledTypeName.get();
192193
}
194+
195+
bool hasSuperclass() const {
196+
return Superclass;
197+
}
198+
199+
std::string getSuperclass() const {
200+
return Superclass.get();
201+
}
193202
};
194203

195204
class FieldDescriptorIterator

include/swift/Reflection/ReflectionContext.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,11 @@ class ReflectionContext
376376
// solve the problem.
377377
while (!CaptureTypes.empty()) {
378378
const TypeRef *OrigCaptureTR = CaptureTypes[0];
379+
380+
// If we failed to demangle the capture type, we cannot proceed.
381+
if (OrigCaptureTR == nullptr)
382+
return nullptr;
383+
379384
const TypeRef *SubstCaptureTR = nullptr;
380385

381386
// If we have enough substitutions to make this captured value's

include/swift/Reflection/TypeRef.h

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -421,28 +421,39 @@ class ProtocolTypeRef final : public TypeRef {
421421
};
422422

423423
class ProtocolCompositionTypeRef final : public TypeRef {
424-
std::vector<const TypeRef *> Protocols;
424+
std::vector<const TypeRef *> Members;
425+
bool HasExplicitAnyObject;
425426

426-
static TypeRefID Profile(const std::vector<const TypeRef *> &Protocols) {
427+
static TypeRefID Profile(const std::vector<const TypeRef *> &Members,
428+
bool HasExplicitAnyObject) {
427429
TypeRefID ID;
428-
for (auto Protocol : Protocols) {
429-
ID.addPointer(Protocol);
430+
ID.addInteger((uint32_t)HasExplicitAnyObject);
431+
for (auto Member : Members) {
432+
ID.addPointer(Member);
430433
}
431434
return ID;
432435
}
433436

434437
public:
435-
ProtocolCompositionTypeRef(std::vector<const TypeRef *> Protocols)
436-
: TypeRef(TypeRefKind::ProtocolComposition), Protocols(Protocols) {}
438+
ProtocolCompositionTypeRef(std::vector<const TypeRef *> Members,
439+
bool HasExplicitAnyObject)
440+
: TypeRef(TypeRefKind::ProtocolComposition),
441+
Members(Members), HasExplicitAnyObject(HasExplicitAnyObject) {}
437442

438443
template <typename Allocator>
439444
static const ProtocolCompositionTypeRef *
440-
create(Allocator &A, std::vector<const TypeRef *> Protocols) {
441-
FIND_OR_CREATE_TYPEREF(A, ProtocolCompositionTypeRef, Protocols);\
445+
create(Allocator &A, std::vector<const TypeRef *> Members,
446+
bool HasExplicitAnyObject) {
447+
FIND_OR_CREATE_TYPEREF(A, ProtocolCompositionTypeRef, Members,
448+
HasExplicitAnyObject);
442449
}
443450

444-
const std::vector<const TypeRef *> &getProtocols() const {
445-
return Protocols;
451+
const std::vector<const TypeRef *> &getMembers() const {
452+
return Members;
453+
}
454+
455+
bool hasExplicitAnyObject() const {
456+
return HasExplicitAnyObject;
446457
}
447458

448459
static bool classof(const TypeRef *TR) {

include/swift/Reflection/TypeRefBuilder.h

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,8 @@ class TypeRefBuilder {
134134
TypeRefBuilder &operator=(const TypeRefBuilder &other) = delete;
135135

136136
private:
137+
Demangle::Demangler Dem;
138+
137139
/// Makes sure dynamically allocated TypeRefs stick around for the life of
138140
/// this TypeRefBuilder and are automatically released.
139141
std::vector<std::unique_ptr<const TypeRef>> TypeRefPool;
@@ -208,17 +210,22 @@ class TypeRefBuilder {
208210

209211
const ProtocolTypeRef *createProtocolType(const std::string &mangledName,
210212
const std::string &moduleName,
213+
const std::string &privateDiscriminator,
211214
const std::string &name) {
212215
return ProtocolTypeRef::create(*this, mangledName);
213216
}
214217

215218
const ProtocolCompositionTypeRef *
216-
createProtocolCompositionType(const std::vector<const TypeRef*> &protocols) {
217-
for (auto protocol : protocols) {
218-
if (!isa<ProtocolTypeRef>(protocol))
219+
createProtocolCompositionType(const std::vector<const TypeRef*> &members,
220+
bool hasExplicitAnyObject) {
221+
for (auto member : members) {
222+
if (!isa<ProtocolTypeRef>(member) &&
223+
!isa<NominalTypeRef>(member) &&
224+
!isa<BoundGenericTypeRef>(member))
219225
return nullptr;
220226
}
221-
return ProtocolCompositionTypeRef::create(*this, protocols);
227+
return ProtocolCompositionTypeRef::create(*this, members,
228+
hasExplicitAnyObject);
222229
}
223230

224231
const ExistentialMetatypeTypeRef *
@@ -314,8 +321,8 @@ class TypeRefBuilder {
314321
const FieldDescriptor *getFieldTypeInfo(const TypeRef *TR);
315322

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

320327
/// Get the primitive type lowering for a builtin type.
321328
const BuiltinTypeDescriptor *getBuiltinTypeInfo(const TypeRef *TR);

include/swift/Remote/MetadataReader.h

Lines changed: 76 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -133,12 +133,55 @@ class TypeDecoder {
133133
}
134134
if (protocols.size() == 1)
135135
return protocols.front();
136-
else
137-
return Builder.createProtocolCompositionType(protocols);
136+
return Builder.createProtocolCompositionType(
137+
protocols,
138+
/*hasExplicitAnyObject=*/false);
139+
}
140+
case NodeKind::ProtocolListWithAnyObject: {
141+
std::vector<BuiltType> protocols;
142+
auto ProtocolList = Node->getChild(0);
143+
auto TypeList = ProtocolList->getChild(0);
144+
for (auto componentType : *TypeList) {
145+
if (auto protocol = decodeMangledType(componentType))
146+
protocols.push_back(protocol);
147+
else
148+
return BuiltType();
149+
}
150+
return Builder.createProtocolCompositionType(
151+
protocols,
152+
/*hasExplicitAnyObject=*/true);
153+
}
154+
case NodeKind::ProtocolListWithClass: {
155+
std::vector<BuiltType> members;
156+
auto ProtocolList = Node->getChild(0);
157+
auto TypeList = ProtocolList->getChild(0);
158+
for (auto componentType : *TypeList) {
159+
if (auto protocol = decodeMangledType(componentType))
160+
members.push_back(protocol);
161+
else
162+
return BuiltType();
163+
}
164+
165+
auto SuperclassNode = Node->getChild(1);
166+
if (auto superclass = decodeMangledType(SuperclassNode))
167+
members.push_back(superclass);
168+
169+
return Builder.createProtocolCompositionType(
170+
members,
171+
/*hasExplicitAnyObject=*/true);
138172
}
139173
case NodeKind::Protocol: {
140174
auto moduleName = Node->getChild(0)->getText();
141-
auto name = Node->getChild(1)->getText();
175+
auto nameNode = Node->getChild(1);
176+
std::string privateDiscriminator, name;
177+
if (nameNode->getKind() == NodeKind::PrivateDeclName) {
178+
privateDiscriminator = nameNode->getChild(0)->getText();
179+
name = nameNode->getChild(1)->getText();
180+
} else if (nameNode->getKind() == NodeKind::Identifier) {
181+
name = Node->getChild(1)->getText();
182+
} else {
183+
return BuiltType();
184+
}
142185

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

152195
auto mangledName = Demangle::mangleNode(protocolList);
153-
return Builder.createProtocolType(mangledName, moduleName, name);
196+
return Builder.createProtocolType(mangledName, moduleName,
197+
privateDiscriminator, name);
154198
}
155199
case NodeKind::DependentGenericParamType: {
156200
auto depth = Node->getChild(0)->getIndex();
@@ -724,7 +768,20 @@ class MetadataReader {
724768
}
725769
case MetadataKind::Existential: {
726770
auto Exist = cast<TargetExistentialTypeMetadata<Runtime>>(Meta);
727-
std::vector<BuiltType> Protocols;
771+
std::vector<BuiltType> Members;
772+
bool HasExplicitAnyObject = false;
773+
774+
if (Exist->Flags.hasSuperclassConstraint()) {
775+
// The superclass is stored after the list of protocols.
776+
auto SuperclassType = readTypeFromMetadata(
777+
Exist->Protocols[Exist->Protocols.NumProtocols]);
778+
if (!SuperclassType) return BuiltType();
779+
Members.push_back(SuperclassType);
780+
}
781+
782+
if (Exist->isClassBounded())
783+
HasExplicitAnyObject = true;
784+
728785
for (size_t i = 0; i < Exist->Protocols.NumProtocols; ++i) {
729786
auto ProtocolAddress = Exist->Protocols[i];
730787
auto ProtocolDescriptor = readProtocolDescriptor(ProtocolAddress);
@@ -741,9 +798,10 @@ class MetadataReader {
741798
if (!Protocol)
742799
return BuiltType();
743800

744-
Protocols.push_back(Protocol);
801+
Members.push_back(Protocol);
745802
}
746-
auto BuiltExist = Builder.createProtocolCompositionType(Protocols);
803+
auto BuiltExist = Builder.createProtocolCompositionType(
804+
Members, HasExplicitAnyObject);
747805
TypeCache[MetadataAddress] = BuiltExist;
748806
return BuiltExist;
749807
}
@@ -1061,6 +1119,14 @@ class MetadataReader {
10611119
case MetadataKind::ErrorObject:
10621120
return _readMetadata<TargetEnumMetadata>(address);
10631121
case MetadataKind::Existential: {
1122+
StoredPointer flagsAddress = address +
1123+
sizeof(StoredPointer);
1124+
1125+
StoredPointer flags;
1126+
if (!Reader->readInteger(RemoteAddress(flagsAddress),
1127+
&flags))
1128+
return nullptr;
1129+
10641130
StoredPointer numProtocolsAddress = address +
10651131
TargetExistentialTypeMetadata<Runtime>::OffsetToNumProtocols;
10661132
StoredPointer numProtocols;
@@ -1076,6 +1142,9 @@ class MetadataReader {
10761142
+ numProtocols *
10771143
sizeof(ConstTargetMetadataPointer<Runtime, TargetProtocolDescriptor>);
10781144

1145+
if (ExistentialTypeFlags(flags).hasSuperclassConstraint())
1146+
totalSize += sizeof(StoredPointer);
1147+
10791148
return _readMetadata(address, totalSize);
10801149
}
10811150
case MetadataKind::ExistentialMetatype:

lib/Demangling/NodePrinter.cpp

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -278,8 +278,10 @@ class NodePrinter {
278278
case Node::Kind::ProtocolList:
279279
return Node->getChild(0)->getNumChildren() <= 1;
280280

281-
case Node::Kind::ProtocolListWithClass:
282281
case Node::Kind::ProtocolListWithAnyObject:
282+
return Node->getChild(0)->getChild(0)->getNumChildren() == 0;
283+
284+
case Node::Kind::ProtocolListWithClass:
283285
case Node::Kind::Allocator:
284286
case Node::Kind::ArgumentTuple:
285287
case Node::Kind::AssociatedTypeMetadataAccessor:
@@ -628,7 +630,8 @@ class NodePrinter {
628630
static bool isExistentialType(NodePointer node) {
629631
return (node->getKind() == Node::Kind::ExistentialMetatype ||
630632
node->getKind() == Node::Kind::ProtocolList ||
631-
node->getKind() == Node::Kind::ProtocolListWithClass);
633+
node->getKind() == Node::Kind::ProtocolListWithClass ||
634+
node->getKind() == Node::Kind::ProtocolListWithAnyObject);
632635
}
633636

634637
/// Print the relevant parameters and return the new index.
@@ -1362,7 +1365,10 @@ NodePointer NodePrinter::print(NodePointer Node, bool asPrefixContext) {
13621365
NodePointer superclass = Node->getChild(1);
13631366
print(superclass);
13641367
Printer << " & ";
1365-
printChildren(protocols, " & ");
1368+
if (protocols->getNumChildren() < 1)
1369+
return nullptr;
1370+
NodePointer type_list = protocols->getChild(0);
1371+
printChildren(type_list, " & ");
13661372
return nullptr;
13671373
}
13681374
case Node::Kind::ProtocolListWithAnyObject: {
@@ -1371,12 +1377,14 @@ NodePointer NodePrinter::print(NodePointer Node, bool asPrefixContext) {
13711377
NodePointer protocols = Node->getChild(0);
13721378
if (protocols->getNumChildren() < 1)
13731379
return nullptr;
1374-
if (protocols->getChild(0)->getNumChildren() == 0) {
1375-
Printer << "AnyObject";
1376-
} else {
1377-
printChildren(protocols->getChild(0), " & ");
1378-
Printer << " & AnyObject";
1380+
NodePointer type_list = protocols->getChild(0);
1381+
if (type_list->getNumChildren() > 0) {
1382+
printChildren(type_list, " & ");
1383+
Printer << " & ";
13791384
}
1385+
if (Options.QualifyEntities)
1386+
Printer << "Swift.";
1387+
Printer << "AnyObject";
13801388
return nullptr;
13811389
}
13821390
case Node::Kind::AssociatedType:

0 commit comments

Comments
 (0)