Skip to content

Commit 46ece0a

Browse files
committed
[Mangling] Separate out base conformance descriptors.
Separate the mangling of base conformance descriptors from that of associated conformance descriptors, and simplify it. (cherry picked from commit e6620b0)
1 parent 16c2981 commit 46ece0a

17 files changed

+140
-27
lines changed

docs/ABI/Mangling.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,8 +200,8 @@ 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
204203
global ::= type assoc-type-list protocol 'TN' // default associated conformance witness accessor
204+
global ::= type protocol 'Tb' // base conformance descriptor
205205

206206
REABSTRACT-THUNK-TYPE ::= 'R' // reabstraction thunk helper function
207207
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: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,7 @@ NODE(MethodDescriptor)
226226
NODE(ProtocolRequirementsBaseDescriptor)
227227
NODE(AssociatedConformanceDescriptor)
228228
NODE(DefaultAssociatedConformanceAccessor)
229+
NODE(BaseConformanceDescriptor)
229230
NODE(AssociatedTypeDescriptor)
230231
NODE(ThrowsAnnotation)
231232
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/Demangler.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2055,21 +2055,28 @@ NodePointer Demangler::demangleThunkOrSpecialization() {
20552055

20562056
case 'n': {
20572057
NodePointer requirementTy = popProtocol();
2058-
NodePointer conformingType = popSelfOrAssocTypePath();
2058+
NodePointer conformingType = popAssocTypePath();
20592059
NodePointer protoTy = popNode(Node::Kind::Type);
20602060
return createWithChildren(Node::Kind::AssociatedConformanceDescriptor,
20612061
protoTy, conformingType, requirementTy);
20622062
}
20632063

20642064
case 'N': {
20652065
NodePointer requirementTy = popProtocol();
2066-
auto assocTypePath = popSelfOrAssocTypePath();
2066+
auto assocTypePath = popAssocTypePath();
20672067
NodePointer protoTy = popNode(Node::Kind::Type);
20682068
return createWithChildren(
20692069
Node::Kind::DefaultAssociatedConformanceAccessor,
20702070
protoTy, assocTypePath, requirementTy);
20712071
}
20722072

2073+
case 'b': {
2074+
NodePointer requirementTy = popProtocol();
2075+
NodePointer protoTy = popNode(Node::Kind::Type);
2076+
return createWithChildren(Node::Kind::BaseConformanceDescriptor,
2077+
protoTy, requirementTy);
2078+
}
2079+
20732080
case 'H':
20742081
case 'h': {
20752082
auto nodeKind = c == 'H' ? Node::Kind::KeyPathEqualsThunkHelper

lib/Demangling/NodePrinter.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,7 @@ class NodePrinter {
319319
case Node::Kind::AssociatedTypeMetadataAccessor:
320320
case Node::Kind::AssociatedTypeWitnessTableAccessor:
321321
case Node::Kind::AutoClosureType:
322+
case Node::Kind::BaseConformanceDescriptor:
322323
case Node::Kind::ClassMetadataBaseOffset:
323324
case Node::Kind::CFunctionPointer:
324325
case Node::Kind::Constructor:
@@ -1637,6 +1638,12 @@ NodePointer NodePrinter::print(NodePointer Node, bool asPrefixContext) {
16371638
Printer << " in ";
16381639
print(Node->getChild(0));
16391640
return nullptr;
1641+
case Node::Kind::BaseConformanceDescriptor:
1642+
Printer << "base conformance descriptor for ";
1643+
print(Node->getChild(0));
1644+
Printer << ": ";
1645+
print(Node->getChild(1));
1646+
return nullptr;
16401647
case Node::Kind::DefaultAssociatedTypeMetadataAccessor:
16411648
Printer << "default associated type metadata accessor for ";
16421649
print(Node->getChild(0));

lib/Demangling/OldRemangler.cpp

Lines changed: 4 additions & 0 deletions
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

lib/Demangling/Remangler.cpp

Lines changed: 5 additions & 0 deletions
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";

lib/IRGen/GenDecl.cpp

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

3539+
llvm::Constant *IRGenModule::getAddrOfBaseConformanceDescriptor(
3540+
BaseConformance conformance) {
3541+
auto entity = LinkEntity::forBaseConformanceDescriptor(conformance);
3542+
return getAddrOfLLVMVariable(entity, ConstantInit(), DebugTypeInfo());
3543+
}
3544+
3545+
llvm::GlobalValue *IRGenModule::defineBaseConformanceDescriptor(
3546+
BaseConformance conformance,
3547+
llvm::Constant *definition) {
3548+
auto entity = LinkEntity::forBaseConformanceDescriptor(conformance);
3549+
return defineAlias(entity, definition);
3550+
}
3551+
35393552
llvm::Constant *IRGenModule::getAddrOfProtocolConformanceDescriptor(
35403553
const RootProtocolConformance *conformance,
35413554
ConstantInit definition) {

lib/IRGen/GenMeta.cpp

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -730,15 +730,10 @@ namespace {
730730
}
731731

732732
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(
733+
// Define a base conformance descriptor, which is just an associated
734+
// conformance descriptor for a base protocol.
735+
BaseConformance conformance(Proto, entry.getBase());
736+
IGM.defineBaseConformanceDescriptor(
742737
conformance,
743738
B.getAddrOfCurrentPosition(IGM.ProtocolRequirementStructTy));
744739
}

0 commit comments

Comments
 (0)