Skip to content

Commit a777c5c

Browse files
committed
[Metadata reader] Separate ObjC and Swift protocol descriptor reading.
When reading the protocol metadata from existential type metadata, check the “isObjC” bit and handle the reading of the Objective-C protocol name (using TargetObjCProtocolPrefix) separately from the reading the name of a Swift protocol (using TargetProtocolDescriptor). More preparation for separating the layout of these two entities.
1 parent 7727e5e commit a777c5c

File tree

2 files changed

+52
-14
lines changed

2 files changed

+52
-14
lines changed

include/swift/ABI/Metadata.h

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1613,14 +1613,6 @@ class TargetProtocolDescriptorRef {
16131613
/// is clear).
16141614
StoredPointer storage;
16151615

1616-
public:
1617-
/// Retrieve the protocol descriptor without checking whether we have an
1618-
/// Objective-C or Swift protocol.
1619-
/// FIXME: Temporarily public while we roll out TargetProtocolDescriptorRef.
1620-
ProtocolDescriptorPointer getProtocolDescriptorUnchecked() const {
1621-
return reinterpret_cast<ProtocolDescriptorPointer>(storage & ~IsObjCBit);
1622-
}
1623-
16241616
constexpr TargetProtocolDescriptorRef(StoredPointer storage)
16251617
: storage(storage) { }
16261618

@@ -1719,7 +1711,7 @@ class TargetProtocolDescriptorRef {
17191711
assert(!isObjC());
17201712
#endif
17211713

1722-
return getProtocolDescriptorUnchecked();
1714+
return reinterpret_cast<ProtocolDescriptorPointer>(storage & ~IsObjCBit);
17231715
}
17241716

17251717
/// Retrieve the raw stored pointer and discriminator bit.
@@ -1734,9 +1726,10 @@ class TargetProtocolDescriptorRef {
17341726
}
17351727

17361728
/// Retrieve the Objective-C protocol.
1737-
Protocol *getObjCProtocol() const {
1729+
TargetPointer<Runtime, Protocol> getObjCProtocol() const {
17381730
assert(isObjC());
1739-
return reinterpret_cast<Protocol *>(storage & ~IsObjCBit);
1731+
return reinterpret_cast<TargetPointer<Runtime, Protocol> >(
1732+
storage & ~IsObjCBit);
17401733
}
17411734
#endif
17421735
};

include/swift/Remote/MetadataReader.h

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "swift/Remote/MemoryReader.h"
2222
#include "swift/Demangling/Demangler.h"
2323
#include "swift/Demangling/TypeDecoder.h"
24+
#include "swift/Basic/Defer.h"
2425
#include "swift/Basic/Range.h"
2526
#include "swift/Basic/LLVM.h"
2627
#include "swift/Runtime/Unreachable.h"
@@ -359,8 +360,31 @@ class MetadataReader {
359360

360361
std::vector<BuiltProtocolDecl> Protocols;
361362
for (auto ProtocolAddress : Exist->getProtocols()) {
362-
auto ProtocolDescriptor = readProtocolDescriptor(
363-
ProtocolAddress.getProtocolDescriptorUnchecked());
363+
#if SWIFT_OBJC_INTEROP
364+
// Check whether we have an Objective-C protocol.
365+
if (ProtocolAddress.isObjC()) {
366+
auto MangledNameStr =
367+
readObjCProtocolName(ProtocolAddress.getObjCProtocol());
368+
369+
StringRef MangledName =
370+
Demangle::dropSwiftManglingPrefix(MangledNameStr);
371+
372+
Demangle::Context DCtx;
373+
auto Demangled = DCtx.demangleTypeAsNode(MangledName);
374+
if (!Demangled)
375+
return BuiltType();
376+
377+
auto Protocol = Builder.createProtocolDecl(Demangled);
378+
if (!Protocol)
379+
return BuiltType();
380+
381+
Protocols.push_back(Protocol);
382+
continue;
383+
}
384+
#endif
385+
386+
auto ProtocolDescriptor = readSwiftProtocolDescriptor(
387+
ProtocolAddress.getSwiftProtocol());
364388
if (!ProtocolDescriptor)
365389
return BuiltType();
366390

@@ -1270,7 +1294,7 @@ class MetadataReader {
12701294
}
12711295

12721296
OwnedProtocolDescriptorRef
1273-
readProtocolDescriptor(StoredPointer Address) {
1297+
readSwiftProtocolDescriptor(StoredPointer Address) {
12741298
auto Size = sizeof(TargetProtocolDescriptor<Runtime>);
12751299
auto Buffer = (uint8_t *)malloc(Size);
12761300
if (!Reader->readBytes(RemoteAddress(Address), Buffer, Size)) {
@@ -1282,6 +1306,27 @@ class MetadataReader {
12821306
return OwnedProtocolDescriptorRef(Casted);
12831307
}
12841308

1309+
#if SWIFT_OBJC_INTEROP
1310+
std::string readObjCProtocolName(StoredPointer Address) {
1311+
auto Size = sizeof(TargetObjCProtocolPrefix<Runtime>);
1312+
auto Buffer = (uint8_t *)malloc(Size);
1313+
SWIFT_DEFER {
1314+
free(Buffer);
1315+
};
1316+
1317+
if (!Reader->readBytes(RemoteAddress(Address), Buffer, Size))
1318+
return std::string();
1319+
1320+
auto ProtocolDescriptor
1321+
= reinterpret_cast<TargetObjCProtocolPrefix<Runtime> *>(Buffer);
1322+
std::string Name;
1323+
if (!Reader->readString(RemoteAddress(ProtocolDescriptor->Name), Name))
1324+
return std::string();
1325+
1326+
return Name;
1327+
}
1328+
#endif
1329+
12851330
// TODO: We need to be able to produce protocol conformances for each
12861331
// substitution type as well in order to accurately rebuild bound generic
12871332
// types or types in protocol-constrained inner contexts.

0 commit comments

Comments
 (0)