[ABI] Rework protocol descriptor metadata.

Reimplement protocol descriptors for Swift protocols as a kind of
context descriptor, dropping the Objective-C protocol compatibility
layout. The new protocol descriptors have several advantages over the
current implementation:

* They drop all of the unused fields required for layout-compatibility
  with Objective-C protocols.
* They encode the full requirement signature of the protocol. This
  maintains more information about the protocol itself, including
  (e.g.) correctly encoding superclass requirements.
* They fit within the general scheme of context descriptors, rather than
  being their own thing, which allows us to share more code with
  nominal type descriptors.
* They only use relative pointers, so they’re smaller and can be placed
  in read-only memory

 Implements rdar://problem/38815359.
This commit is contained in:
Doug Gregor
2018-07-23 17:01:13 -07:00
parent c56879da73
commit a54a6d8d7f
21 changed files with 528 additions and 550 deletions

View File

@@ -451,7 +451,7 @@ _searchProtocolRecords(ProtocolMetadataPrivateState &C,
if (auto protocol = record.Protocol.getPointer()) {
// Drop the "S$" prefix from the protocol record. It's not used in
// the type itself.
StringRef foundProtocolName = protocol->Name;
StringRef foundProtocolName = protocol->Name.get();
assert(foundProtocolName.startswith("$S"));
foundProtocolName = foundProtocolName.drop_front(2);
if (foundProtocolName == protocolName)
@@ -644,9 +644,6 @@ namespace {
/// the given name in the given protocol descriptor.
Optional<unsigned> findAssociatedTypeByName(const ProtocolDescriptor *protocol,
StringRef name) {
// Only Swift protocols have associated types.
if (!protocol->Flags.isSwift()) return None;
// If we don't have associated type names, there's nothing to do.
const char *associatedTypeNamesPtr = protocol->AssociatedTypeNames.get();
if (!associatedTypeNamesPtr) return None;
@@ -672,7 +669,7 @@ Optional<unsigned> findAssociatedTypeByName(const ProtocolDescriptor *protocol,
// type requirement.
unsigned currentAssocTypeIdx = 0;
unsigned numRequirements = protocol->NumRequirements;
const ProtocolRequirement *requirements = protocol->Requirements.get();
auto requirements = protocol->getRequirements();
for (unsigned reqIdx = 0; reqIdx != numRequirements; ++reqIdx) {
if (requirements[reqIdx].Flags.getKind() !=
ProtocolRequirementFlags::Kind::AssociatedTypeAccessFunction)