Skip to content

Commit 7679433

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.
1 parent e52a883 commit 7679433

File tree

9 files changed

+48
-24
lines changed

9 files changed

+48
-24
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;
@@ -2048,15 +2062,15 @@ NodePointer Demangler::demangleThunkOrSpecialization() {
20482062

20492063
case 'n': {
20502064
NodePointer requirementTy = popProtocol();
2051-
auto assocTypePath = popAssocTypePath();
2065+
NodePointer conformingType = popSelfOrAssocTypePath();
20522066
NodePointer protoTy = popNode(Node::Kind::Type);
20532067
return createWithChildren(Node::Kind::AssociatedConformanceDescriptor,
2054-
protoTy, assocTypePath, requirementTy);
2068+
protoTy, conformingType, requirementTy);
20552069
}
20562070

20572071
case 'N': {
20582072
NodePointer requirementTy = popProtocol();
2059-
auto assocTypePath = popAssocTypePath();
2073+
auto assocTypePath = popSelfOrAssocTypePath();
20602074
NodePointer protoTy = popNode(Node::Kind::Type);
20612075
return createWithChildren(
20622076
Node::Kind::DefaultAssociatedConformanceAccessor,
@@ -2437,19 +2451,7 @@ NodePointer Demangler::demangleWitness() {
24372451
}
24382452
case 'T': {
24392453
NodePointer ProtoTy = popNode(Node::Kind::Type);
2440-
NodePointer ConformingType = nullptr;
2441-
if (auto Type = popNode(Node::Kind::Type)) {
2442-
if (Type->getChild(0) &&
2443-
Type->getChild(0)->getKind() ==
2444-
Node::Kind::DependentGenericParamType) {
2445-
ConformingType = Type;
2446-
} else {
2447-
pushNode(Type);
2448-
}
2449-
}
2450-
2451-
if (!ConformingType)
2452-
ConformingType = popAssocTypePath();
2454+
NodePointer ConformingType = popSelfOrAssocTypePath();
24532455
NodePointer Conf = popProtocolConformance();
24542456
return createWithChildren(Node::Kind::AssociatedTypeWitnessTableAccessor,
24552457
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
@@ -431,10 +431,6 @@ void TBDGenVisitor::visitProtocolDecl(ProtocolDecl *PD) {
431431
if (req.getKind() != RequirementKind::Conformance)
432432
continue;
433433

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

test/Demangle/Inputs/manglings.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,3 +335,4 @@ $S1t1PP10AssocType2_AA1QTN ---> default associated conformance accessor for t.P.
335335
$sSD5IndexVy__GD ---> $sSD5IndexVy__GD
336336
$s4test3StrCACycfC ---> {T:$s4test3StrCACycfc} test.Str.__allocating_init() -> test.Str
337337
$s18keypaths_inlinable13KeypathStructV8computedSSvpACTKq ---> key path getter for keypaths_inlinable.KeypathStruct.computed : Swift.String : keypaths_inlinable.KeypathStruct, serialized
338+
$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)