Skip to content

Commit 850a2a7

Browse files
committed
[Metadata reader] Factor out reading metadata for a protocol reference.
Protocol references are interesting because we have to deal with the low bit indicating whether we have a reference to an Objective-C protocol. Factor out this logic for later re-use.
1 parent cc36090 commit 850a2a7

File tree

1 file changed

+70
-52
lines changed

1 file changed

+70
-52
lines changed

include/swift/Remote/MetadataReader.h

Lines changed: 70 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,54 @@ class MetadataReader {
397397
{RemoteAddress(MetadataAddress), RemoteAddress(StartOfValue)});
398398
}
399399

400+
/// Read a protocol from a reference to said protocol.
401+
template<typename Resolver>
402+
typename Resolver::Result readProtocol(
403+
const TargetProtocolDescriptorRef<Runtime> &ProtocolAddress,
404+
Demangler &dem,
405+
Resolver resolver) {
406+
#if SWIFT_OBJC_INTEROP
407+
// Check whether we have an Objective-C protocol.
408+
if (ProtocolAddress.isObjC()) {
409+
auto Name = readObjCProtocolName(ProtocolAddress.getObjCProtocol());
410+
StringRef NameStr(Name);
411+
412+
// If this is a Swift-defined protocol, demangle it.
413+
if (NameStr.startswith("_TtP")) {
414+
auto Demangled = dem.demangleSymbol(NameStr);
415+
if (!Demangled)
416+
return resolver.failure();
417+
418+
// FIXME: This appears in _swift_buildDemanglingForMetadata().
419+
while (Demangled->getKind() == Node::Kind::Global ||
420+
Demangled->getKind() == Node::Kind::TypeMangling ||
421+
Demangled->getKind() == Node::Kind::Type ||
422+
Demangled->getKind() == Node::Kind::ProtocolList ||
423+
Demangled->getKind() == Node::Kind::TypeList ||
424+
Demangled->getKind() == Node::Kind::Type) {
425+
if (Demangled->getNumChildren() != 1)
426+
return resolver.failure();
427+
Demangled = Demangled->getFirstChild();
428+
}
429+
430+
return resolver.swiftProtocol(Demangled);
431+
}
432+
433+
// Otherwise, this is an imported protocol.
434+
return resolver.objcProtocol(NameStr);
435+
}
436+
#endif
437+
438+
// Swift-native protocol.
439+
auto Demangled =
440+
readDemanglingForContextDescriptor(ProtocolAddress.getSwiftProtocol(),
441+
dem);
442+
if (!Demangled)
443+
return resolver.failure();
444+
445+
return resolver.swiftProtocol(Demangled);
446+
}
447+
400448
/// Given a remote pointer to metadata, attempt to turn it into a type.
401449
BuiltType readTypeFromMetadata(StoredPointer MetadataAddress,
402450
bool skipArtificialSubclasses = false) {
@@ -493,64 +541,34 @@ class MetadataReader {
493541
HasExplicitAnyObject = true;
494542
}
495543

496-
std::vector<BuiltProtocolDecl> Protocols;
497-
for (auto ProtocolAddress : Exist->getProtocols()) {
498-
#if SWIFT_OBJC_INTEROP
499-
// Check whether we have an Objective-C protocol.
500-
if (ProtocolAddress.isObjC()) {
501-
auto Name =
502-
readObjCProtocolName(ProtocolAddress.getObjCProtocol());
503-
StringRef NameStr(Name);
504-
505-
// If this is a Swift-defined protocol, demangle it.
506-
if (NameStr.startswith("_TtP")) {
507-
Demangle::Context DCtx;
508-
auto Demangled = DCtx.demangleSymbolAsNode(NameStr);
509-
if (!Demangled)
510-
return BuiltType();
511-
512-
// FIXME: This appears in _swift_buildDemanglingForMetadata().
513-
while (Demangled->getKind() == Node::Kind::Global ||
514-
Demangled->getKind() == Node::Kind::TypeMangling ||
515-
Demangled->getKind() == Node::Kind::Type ||
516-
Demangled->getKind() == Node::Kind::ProtocolList ||
517-
Demangled->getKind() == Node::Kind::TypeList ||
518-
Demangled->getKind() == Node::Kind::Type) {
519-
if (Demangled->getNumChildren() != 1)
520-
return BuiltType();
521-
Demangled = Demangled->getFirstChild();
522-
}
523-
524-
auto Protocol = Builder.createProtocolDecl(Demangled);
525-
if (!Protocol)
526-
return BuiltType();
527-
528-
Protocols.push_back(Protocol);
529-
continue;
530-
}
544+
/// Resolver to turn a protocol reference into a protocol declaration.
545+
struct ProtocolResolver {
546+
using Result = BuiltProtocolDecl;
531547

532-
// Otherwise, this is an imported protocol.
533-
auto Protocol = Builder.createObjCProtocolDecl(NameStr);
534-
if (!Protocol)
535-
return BuiltType();
548+
BuilderType &builder;
536549

537-
Protocols.push_back(Protocol);
538-
continue;
550+
BuiltProtocolDecl failure() const {
551+
return BuiltProtocolDecl();
539552
}
540-
#endif
541553

542-
// Swift-native protocol.
543-
Demangle::Demangler Dem;
544-
auto Demangled = readDemanglingForContextDescriptor(
545-
ProtocolAddress.getSwiftProtocol(), Dem);
546-
if (!Demangled)
547-
return BuiltType();
554+
BuiltProtocolDecl swiftProtocol(Demangle::Node *node) {
555+
return builder.createProtocolDecl(node);
556+
}
548557

549-
auto Protocol = Builder.createProtocolDecl(Demangled);
550-
if (!Protocol)
551-
return BuiltType();
558+
#if SWIFT_OBJC_INTEROP
559+
BuiltProtocolDecl objcProtocol(StringRef name) {
560+
return builder.createObjCProtocolDecl(name);
561+
}
562+
#endif
563+
} resolver{Builder};
552564

553-
Protocols.push_back(Protocol);
565+
Demangler dem;
566+
std::vector<BuiltProtocolDecl> Protocols;
567+
for (auto ProtocolAddress : Exist->getProtocols()) {
568+
if (auto Protocol = readProtocol(ProtocolAddress, dem, resolver))
569+
Protocols.push_back(Protocol);
570+
else
571+
return BuiltType();
554572
}
555573
auto BuiltExist = Builder.createProtocolCompositionType(
556574
Protocols, SuperclassType, HasExplicitAnyObject);

0 commit comments

Comments
 (0)