Skip to content

Commit 7ec471b

Browse files
authored
Merge pull request #21023 from DougGregor/mangled-base-protocol-witnesses-5.0
[5.0] [ABI] Use mangled names for base protocol witnesses
2 parents 261b128 + 565e992 commit 7ec471b

30 files changed

+334
-194
lines changed

docs/ABI/Mangling.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,8 @@ Globals
146146
global ::= type protocol-conformance 'WL' // lazy protocol witness table cache variable
147147

148148
global ::= protocol-conformance identifier 'Wt' // associated type metadata accessor (HISTORICAL)
149-
global ::= protocol-conformance assoc-type-list nominal-type 'WT' // associated type witness table accessor
149+
global ::= protocol-conformance assoc-type-list protocol 'WT' // associated type witness table accessor
150+
global ::= protocol-conformance protocol 'Wb' // base protocol witness table accessor
150151
global ::= type protocol-conformance 'Wl' // lazy protocol witness table accessor
151152

152153
global ::= type 'WV' // value witness table
@@ -200,6 +201,7 @@ types where the metadata itself has unknown layout.)
200201
global ::= assoc-type-name 'TM' // default associated type witness accessor (HISTORICAL)
201202
global ::= type assoc-type-list protocol 'Tn' // associated conformance descriptor
202203
global ::= type assoc-type-list protocol 'TN' // default associated conformance witness accessor
204+
global ::= type protocol 'Tb' // base conformance descriptor
203205

204206
REABSTRACT-THUNK-TYPE ::= 'R' // reabstraction thunk helper function
205207
REABSTRACT-THUNK-TYPE ::= 'r' // reabstraction thunk

include/swift/AST/ProtocolAssociations.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,27 @@ class AssociatedType {
6868
}
6969
};
7070

71+
/// A base conformance of a protocol.
72+
class BaseConformance {
73+
ProtocolDecl *Source;
74+
ProtocolDecl *Requirement;
75+
76+
public:
77+
explicit BaseConformance(ProtocolDecl *source,
78+
ProtocolDecl *requirement)
79+
: Source(source), Requirement(requirement) {
80+
assert(source && requirement);
81+
}
82+
83+
ProtocolDecl *getSourceProtocol() const {
84+
return Source;
85+
}
86+
87+
ProtocolDecl *getBaseRequirement() const {
88+
return Requirement;
89+
}
90+
};
91+
7192
/// A conformance associated with a protocol.
7293
class AssociatedConformance {
7394
ProtocolDecl *Source;

include/swift/Demangling/DemangleNodes.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ NODE(AssociatedTypeRef)
3333
NODE(AssociatedTypeMetadataAccessor)
3434
NODE(DefaultAssociatedTypeMetadataAccessor)
3535
NODE(AssociatedTypeWitnessTableAccessor)
36+
NODE(BaseWitnessTableAccessor)
3637
NODE(AutoClosureType)
3738
NODE(BoundGenericClass)
3839
NODE(BoundGenericEnum)
@@ -226,6 +227,7 @@ NODE(MethodDescriptor)
226227
NODE(ProtocolRequirementsBaseDescriptor)
227228
NODE(AssociatedConformanceDescriptor)
228229
NODE(DefaultAssociatedConformanceAccessor)
230+
NODE(BaseConformanceDescriptor)
229231
NODE(AssociatedTypeDescriptor)
230232
NODE(ThrowsAnnotation)
231233
NODE(EmptyList)

include/swift/IRGen/Linking.h

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,13 @@ class LinkEntity {
230230
/// is stored in the data.
231231
DefaultAssociatedConformanceAccessor,
232232

233+
/// An descriptor for an base conformance within a protocol, which
234+
/// will alias the TargetProtocolRequirement descripting this
235+
/// particular base conformance.
236+
/// The pointer is a ProtocolDecl*; the index of the base conformance
237+
/// is stored in the data.
238+
BaseConformanceDescriptor,
239+
233240
/// A global function pointer for dynamically replaceable functions.
234241
/// The pointer is a AbstractStorageDecl*.
235242
DynamicallyReplaceableFunctionVariableAST,
@@ -810,6 +817,18 @@ class LinkEntity {
810817
return entity;
811818
}
812819

820+
static LinkEntity
821+
forBaseConformanceDescriptor(BaseConformance conformance) {
822+
LinkEntity entity;
823+
entity.setForProtocolAndAssociatedConformance(
824+
Kind::BaseConformanceDescriptor,
825+
conformance.getSourceProtocol(),
826+
conformance.getSourceProtocol()->getSelfInterfaceType()
827+
->getCanonicalType(),
828+
conformance.getBaseRequirement());
829+
return entity;
830+
}
831+
813832
static LinkEntity
814833
forAssociatedTypeWitnessTableAccessFunction(const ProtocolConformance *C,
815834
const AssociatedConformance &association) {
@@ -963,7 +982,8 @@ class LinkEntity {
963982
}
964983

965984
assert(getKind() == Kind::AssociatedConformanceDescriptor ||
966-
getKind() == Kind::DefaultAssociatedConformanceAccessor);
985+
getKind() == Kind::DefaultAssociatedConformanceAccessor ||
986+
getKind() == Kind::BaseConformanceDescriptor);
967987
return getAssociatedConformanceByIndex(
968988
cast<ProtocolDecl>(getDecl()),
969989
LINKENTITY_GET_FIELD(Data, AssociatedConformanceIndex));

lib/Demangling/Context.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ bool Context::hasSwiftCallingConvention(llvm::StringRef MangledName) {
162162
case Node::Kind::LazyProtocolWitnessTableAccessor:
163163
case Node::Kind::AssociatedTypeMetadataAccessor:
164164
case Node::Kind::AssociatedTypeWitnessTableAccessor:
165+
case Node::Kind::BaseWitnessTableAccessor:
165166
case Node::Kind::ObjCAttribute:
166167
return false;
167168
default:

lib/Demangling/Demangler.cpp

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2041,10 +2041,10 @@ NodePointer Demangler::demangleThunkOrSpecialization() {
20412041

20422042
case 'n': {
20432043
NodePointer requirementTy = popProtocol();
2044-
auto assocTypePath = popAssocTypePath();
2044+
NodePointer conformingType = popAssocTypePath();
20452045
NodePointer protoTy = popNode(Node::Kind::Type);
20462046
return createWithChildren(Node::Kind::AssociatedConformanceDescriptor,
2047-
protoTy, assocTypePath, requirementTy);
2047+
protoTy, conformingType, requirementTy);
20482048
}
20492049

20502050
case 'N': {
@@ -2056,6 +2056,13 @@ NodePointer Demangler::demangleThunkOrSpecialization() {
20562056
protoTy, assocTypePath, requirementTy);
20572057
}
20582058

2059+
case 'b': {
2060+
NodePointer requirementTy = popProtocol();
2061+
NodePointer protoTy = popNode(Node::Kind::Type);
2062+
return createWithChildren(Node::Kind::BaseConformanceDescriptor,
2063+
protoTy, requirementTy);
2064+
}
2065+
20592066
case 'H':
20602067
case 'h': {
20612068
auto nodeKind = c == 'H' ? Node::Kind::KeyPathEqualsThunkHelper
@@ -2423,11 +2430,16 @@ NodePointer Demangler::demangleWitness() {
24232430
}
24242431
case 'T': {
24252432
NodePointer ProtoTy = popNode(Node::Kind::Type);
2426-
auto AssocTypePath = popAssocTypePath();
2427-
2433+
NodePointer ConformingType = popAssocTypePath();
24282434
NodePointer Conf = popProtocolConformance();
24292435
return createWithChildren(Node::Kind::AssociatedTypeWitnessTableAccessor,
2430-
Conf, AssocTypePath, ProtoTy);
2436+
Conf, ConformingType, ProtoTy);
2437+
}
2438+
case 'b': {
2439+
NodePointer ProtoTy = popNode(Node::Kind::Type);
2440+
NodePointer Conf = popProtocolConformance();
2441+
return createWithChildren(Node::Kind::BaseWitnessTableAccessor,
2442+
Conf, ProtoTy);
24312443
}
24322444
case 'O': {
24332445
switch (nextChar()) {

lib/Demangling/NodePrinter.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,8 @@ class NodePrinter {
319319
case Node::Kind::AssociatedTypeMetadataAccessor:
320320
case Node::Kind::AssociatedTypeWitnessTableAccessor:
321321
case Node::Kind::AutoClosureType:
322+
case Node::Kind::BaseConformanceDescriptor:
323+
case Node::Kind::BaseWitnessTableAccessor:
322324
case Node::Kind::ClassMetadataBaseOffset:
323325
case Node::Kind::CFunctionPointer:
324326
case Node::Kind::Constructor:
@@ -1637,6 +1639,12 @@ NodePointer NodePrinter::print(NodePointer Node, bool asPrefixContext) {
16371639
Printer << " in ";
16381640
print(Node->getChild(0));
16391641
return nullptr;
1642+
case Node::Kind::BaseConformanceDescriptor:
1643+
Printer << "base conformance descriptor for ";
1644+
print(Node->getChild(0));
1645+
Printer << ": ";
1646+
print(Node->getChild(1));
1647+
return nullptr;
16401648
case Node::Kind::DefaultAssociatedTypeMetadataAccessor:
16411649
Printer << "default associated type metadata accessor for ";
16421650
print(Node->getChild(0));
@@ -1649,6 +1657,12 @@ NodePointer NodePrinter::print(NodePointer Node, bool asPrefixContext) {
16491657
Printer << " in ";
16501658
print(Node->getChild(0));
16511659
return nullptr;
1660+
case Node::Kind::BaseWitnessTableAccessor:
1661+
Printer << "base witness table accessor for ";
1662+
print(Node->getChild(1));
1663+
Printer << " in ";
1664+
print(Node->getChild(0));
1665+
return nullptr;
16521666
case Node::Kind::ClassMetadataBaseOffset:
16531667
Printer << "class metadata base offset for ";
16541668
print(Node->getChild(0));

lib/Demangling/OldRemangler.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -942,6 +942,10 @@ void Remangler::mangleDefaultAssociatedConformanceAccessor(Node *node) {
942942
Out << "<default-associated-conformance-descriptor>";
943943
}
944944

945+
void Remangler::mangleBaseConformanceDescriptor(Node *node) {
946+
Out << "<base-conformance-descriptor>";
947+
}
948+
945949
void Remangler::mangleAssociatedTypeMetadataAccessor(Node *node) {
946950
Out << "Wt";
947951
mangleChildNodes(node); // protocol conformance, identifier
@@ -955,10 +959,14 @@ void Remangler::mangleAssociatedTypeWitnessTableAccessor(Node *node) {
955959
Out << "WT";
956960
assert(node->getNumChildren() == 3);
957961
mangleChildNode(node, 0); // protocol conformance
958-
mangleChildNode(node, 1); // identifier
962+
mangleChildNode(node, 1); // type
959963
mangleProtocolWithoutPrefix(node->begin()[2]); // type
960964
}
961965

966+
void Remangler::mangleBaseWitnessTableAccessor(Node *node) {
967+
Out << "<base-witness-table-accessor>";
968+
}
969+
962970
void Remangler::mangleReabstractionThunkHelper(Node *node) {
963971
Out << "TR";
964972
if (node->getNumChildren() == 3) Out << 'G';

lib/Demangling/Remangler.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,11 @@ void Remangler::mangleDefaultAssociatedConformanceAccessor(Node *node) {
585585
Buffer << "TN";
586586
}
587587

588+
void Remangler::mangleBaseConformanceDescriptor(Node *node) {
589+
mangleChildNodes(node);
590+
Buffer << "Tb";
591+
}
592+
588593
void Remangler::mangleAssociatedTypeMetadataAccessor(Node *node) {
589594
mangleChildNodes(node); // protocol conformance, identifier
590595
Buffer << "Wt";
@@ -596,10 +601,15 @@ void Remangler::mangleDefaultAssociatedTypeMetadataAccessor(Node *node) {
596601
}
597602

598603
void Remangler::mangleAssociatedTypeWitnessTableAccessor(Node *node) {
599-
mangleChildNodes(node); // protocol conformance, identifier, type
604+
mangleChildNodes(node); // protocol conformance, type, protocol
600605
Buffer << "WT";
601606
}
602607

608+
void Remangler::mangleBaseWitnessTableAccessor(Node *node) {
609+
mangleChildNodes(node); // protocol conformance, protocol
610+
Buffer << "Wb";
611+
}
612+
603613
void Remangler::mangleAutoClosureType(Node *node) {
604614
mangleChildNodesReversed(node); // argument tuple, result type
605615
Buffer << "XK";

lib/IRGen/GenDecl.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3530,6 +3530,19 @@ llvm::GlobalValue *IRGenModule::defineAssociatedConformanceDescriptor(
35303530
return defineAlias(entity, definition);
35313531
}
35323532

3533+
llvm::Constant *IRGenModule::getAddrOfBaseConformanceDescriptor(
3534+
BaseConformance conformance) {
3535+
auto entity = LinkEntity::forBaseConformanceDescriptor(conformance);
3536+
return getAddrOfLLVMVariable(entity, ConstantInit(), DebugTypeInfo());
3537+
}
3538+
3539+
llvm::GlobalValue *IRGenModule::defineBaseConformanceDescriptor(
3540+
BaseConformance conformance,
3541+
llvm::Constant *definition) {
3542+
auto entity = LinkEntity::forBaseConformanceDescriptor(conformance);
3543+
return defineAlias(entity, definition);
3544+
}
3545+
35333546
llvm::Constant *IRGenModule::getAddrOfProtocolConformanceDescriptor(
35343547
const RootProtocolConformance *conformance,
35353548
ConstantInit definition) {

0 commit comments

Comments
 (0)