Skip to content

Commit 456d7c3

Browse files
committed
[ABI] Emit associated conformance descriptors for inherited protocols.
Start emitting associated conformance requirement descriptors for inherited protocols, so we have a symbol to reference from resilient witness tables and mangled names in the future. (cherry picked from commit 7679433)
1 parent edb7a5f commit 456d7c3

File tree

9 files changed

+48
-25
lines changed

9 files changed

+48
-25
lines changed

docs/ABI/Mangling.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ types where the metadata itself has unknown layout.)
200200
global ::= assoc-type-name 'Tl' // associated type descriptor
201201
global ::= assoc-type-name 'TM' // default associated type witness accessor (HISTORICAL)
202202
global ::= type assoc-type-list protocol 'Tn' // associated conformance descriptor
203+
global ::= type type protocol 'Tn' // inherited protocol witness descriptor
203204
global ::= type assoc-type-list protocol 'TN' // default associated conformance witness accessor
204205

205206
REABSTRACT-THUNK-TYPE ::= 'R' // reabstraction thunk helper function

include/swift/Demangling/Demangler.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,7 @@ class Demangler : public NodeFactory {
455455

456456
NodePointer popAssocTypeName();
457457
NodePointer popAssocTypePath();
458+
NodePointer popSelfOrAssocTypePath();
458459
NodePointer getDependentGenericParamType(int depth, int index);
459460
NodePointer demangleGenericParamIndex();
460461
NodePointer popProtocolConformance();

lib/Demangling/Demangler.cpp

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1875,6 +1875,20 @@ NodePointer Demangler::popAssocTypePath() {
18751875
return AssocTypePath;
18761876
}
18771877

1878+
NodePointer Demangler::popSelfOrAssocTypePath() {
1879+
if (auto Type = popNode(Node::Kind::Type)) {
1880+
if (Type->getChild(0) &&
1881+
Type->getChild(0)->getKind() ==
1882+
Node::Kind::DependentGenericParamType) {
1883+
return Type;
1884+
}
1885+
1886+
pushNode(Type);
1887+
}
1888+
1889+
return popAssocTypePath();
1890+
}
1891+
18781892
NodePointer Demangler::getDependentGenericParamType(int depth, int index) {
18791893
if (depth < 0 || index < 0)
18801894
return nullptr;
@@ -2041,15 +2055,15 @@ NodePointer Demangler::demangleThunkOrSpecialization() {
20412055

20422056
case 'n': {
20432057
NodePointer requirementTy = popProtocol();
2044-
auto assocTypePath = popAssocTypePath();
2058+
NodePointer conformingType = popSelfOrAssocTypePath();
20452059
NodePointer protoTy = popNode(Node::Kind::Type);
20462060
return createWithChildren(Node::Kind::AssociatedConformanceDescriptor,
2047-
protoTy, assocTypePath, requirementTy);
2061+
protoTy, conformingType, requirementTy);
20482062
}
20492063

20502064
case 'N': {
20512065
NodePointer requirementTy = popProtocol();
2052-
auto assocTypePath = popAssocTypePath();
2066+
auto assocTypePath = popSelfOrAssocTypePath();
20532067
NodePointer protoTy = popNode(Node::Kind::Type);
20542068
return createWithChildren(
20552069
Node::Kind::DefaultAssociatedConformanceAccessor,
@@ -2423,19 +2437,7 @@ NodePointer Demangler::demangleWitness() {
24232437
}
24242438
case 'T': {
24252439
NodePointer ProtoTy = popNode(Node::Kind::Type);
2426-
NodePointer ConformingType = nullptr;
2427-
if (auto Type = popNode(Node::Kind::Type)) {
2428-
if (Type->getChild(0) &&
2429-
Type->getChild(0)->getKind() ==
2430-
Node::Kind::DependentGenericParamType) {
2431-
ConformingType = Type;
2432-
} else {
2433-
pushNode(Type);
2434-
}
2435-
}
2436-
2437-
if (!ConformingType)
2438-
ConformingType = popAssocTypePath();
2440+
NodePointer ConformingType = popSelfOrAssocTypePath();
24392441
NodePointer Conf = popProtocolConformance();
24402442
return createWithChildren(Node::Kind::AssociatedTypeWitnessTableAccessor,
24412443
Conf, ConformingType, ProtoTy);

lib/IRGen/GenMeta.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -729,6 +729,20 @@ namespace {
729729
B.getAddrOfCurrentPosition(IGM.ProtocolRequirementStructTy));
730730
}
731731

732+
if (entry.isBase()) {
733+
// Define the associated conformance descriptor to point to the
734+
// current position in the protocol descriptor, which is an
735+
// out-of-line base protocol.
736+
AssociatedConformance conformance(
737+
Proto,
738+
Proto->getProtocolSelfType()
739+
->getCanonicalType(),
740+
entry.getBase());
741+
IGM.defineAssociatedConformanceDescriptor(
742+
conformance,
743+
B.getAddrOfCurrentPosition(IGM.ProtocolRequirementStructTy));
744+
}
745+
732746
auto reqt = B.beginStruct(IGM.ProtocolRequirementStructTy);
733747

734748
auto info = getRequirementInfo(entry);

lib/IRGen/IRGenMangler.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,8 +197,12 @@ class IRGenMangler : public Mangle::ASTMangler {
197197
const ProtocolDecl *requirement) {
198198
beginMangling();
199199
appendAnyGenericType(proto);
200-
bool isFirstAssociatedTypeIdentifier = true;
201-
appendAssociatedTypePath(subject, isFirstAssociatedTypeIdentifier);
200+
if (isa<GenericTypeParamType>(subject)) {
201+
appendType(subject);
202+
} else {
203+
bool isFirstAssociatedTypeIdentifier = true;
204+
appendAssociatedTypePath(subject, isFirstAssociatedTypeIdentifier);
205+
}
202206
appendProtocolName(requirement);
203207
appendOperator("Tn");
204208
return finalize();

lib/IRGen/Linking.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -880,8 +880,10 @@ bool LinkEntity::isWeakImported(ModuleDecl *module) const {
880880
// their declaration, but are weak linked if the associated
881881
// type stored in extra storage area is weak linked.
882882
auto assocConformance = getAssociatedConformance();
883-
auto *depMemTy = assocConformance.first->castTo<DependentMemberType>();
884-
return depMemTy->getAssocType()->isWeakImported(module);
883+
if (auto *depMemTy = assocConformance.first->getAs<DependentMemberType>())
884+
return depMemTy->getAssocType()->isWeakImported(module);
885+
886+
return cast<ProtocolDecl>(getDecl())->isWeakImported(module);
885887
}
886888

887889
case Kind::TypeMetadata:

lib/TBDGen/TBDGen.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -432,10 +432,6 @@ void TBDGenVisitor::visitProtocolDecl(ProtocolDecl *PD) {
432432
if (req.getKind() != RequirementKind::Conformance)
433433
continue;
434434

435-
// Skip inherited requirements.
436-
if (req.getFirstType()->isEqual(PD->getSelfInterfaceType()))
437-
continue;
438-
439435
AssociatedConformance conformance(
440436
PD,
441437
req.getFirstType()->getCanonicalType(),

test/Demangle/Inputs/manglings.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -334,4 +334,4 @@ $S1t1PP10AssocType2_AA1QTn ---> associated conformance descriptor for t.P.AssocT
334334
$S1t1PP10AssocType2_AA1QTN ---> default associated conformance accessor for t.P.AssocType2: t.Q
335335
$sSD5IndexVy__GD ---> $sSD5IndexVy__GD
336336
$s4test3StrCACycfC ---> {T:$s4test3StrCACycfc} test.Str.__allocating_init() -> test.Str
337-
337+
$s18resilient_protocol24ResilientDerivedProtocolPxAA0c4BaseE0Tn --> associated conformance descriptor for resilient_protocol.ResilientDerivedProtocol.A: resilient_protocol.ResilientBaseProtocol

test/IRGen/protocol_resilience_descriptors.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@
2929
// Protocol requirements base descriptor
3030
// CHECK-DEFINITION: @"$s18resilient_protocol21ResilientBaseProtocolTL" ={{( dllexport)?}}{{( protected)?}} alias %swift.protocol_requirement, getelementptr (%swift.protocol_requirement, %swift.protocol_requirement* getelementptr inbounds (<{ i32, i32, i32, i32, i32, i32, %swift.protocol_requirement }>, <{ i32, i32, i32, i32, i32, i32, %swift.protocol_requirement }>* @"$s18resilient_protocol21ResilientBaseProtocolMp", i32 0, i32 6), i32 -1)
3131

32+
// Associated conformance descriptor for inherited protocol
33+
// CHECK-DEFINITION-LABEL: s18resilient_protocol24ResilientDerivedProtocolPxAA0c4BaseE0Tn" = alias
34+
3235
// Associated type and conformance
3336

3437
// CHECK-DEFINITION: @"$s1T18resilient_protocol24ProtocolWithRequirementsPTl" ={{( dllexport)?}}{{( protected)?}} alias

0 commit comments

Comments
 (0)