Skip to content

Commit b5ae8c4

Browse files
committed
AST: Add mangling for class-constrained existentials
1 parent c38f53d commit b5ae8c4

File tree

6 files changed

+58
-5
lines changed

6 files changed

+58
-5
lines changed

docs/ABI.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,6 +1044,7 @@ Types
10441044
type ::= associated-type
10451045
type ::= nominal-type
10461046
type ::= protocol-list 'p' // existential type
1047+
type ::= protocol-list superclass 'XE' // existential type with superclass
10471048
type ::= type-list 't' // tuple
10481049
type ::= type generic-signature 'u' // generic type
10491050
type ::= 'x' // generic param, depth=0, idx=0

include/swift/Demangling/DemangleNodes.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ CONTEXT_NODE(Protocol)
123123
NODE(ProtocolConformance)
124124
NODE(ProtocolDescriptor)
125125
NODE(ProtocolList)
126+
NODE(ProtocolListWithClass)
126127
NODE(ProtocolWitness)
127128
NODE(ProtocolWitnessTable)
128129
NODE(ProtocolWitnessTableAccessor)

lib/AST/ASTMangler.cpp

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "swift/AST/ASTMangler.h"
1818
#include "swift/AST/ASTContext.h"
1919
#include "swift/AST/ASTVisitor.h"
20+
#include "swift/AST/ExistentialLayout.h"
2021
#include "swift/AST/GenericEnvironment.h"
2122
#include "swift/AST/Initializer.h"
2223
#include "swift/AST/Module.h"
@@ -631,16 +632,32 @@ void ASTMangler::appendType(Type type) {
631632
appendTypeList(type);
632633
return appendOperator("t");
633634

634-
case TypeKind::Protocol:
635+
case TypeKind::Protocol: {
636+
bool First = true;
637+
appendProtocolName(cast<ProtocolType>(tybase)->getDecl());
638+
appendListSeparator(First);
639+
return appendOperator("p");
640+
}
641+
635642
case TypeKind::ProtocolComposition: {
636643
// We mangle ProtocolType and ProtocolCompositionType using the
637644
// same production:
638645
bool First = true;
639-
appendProtocolList(type, First);
646+
auto layout = type->getExistentialLayout();
647+
for (Type protoTy : layout.getProtocols()) {
648+
appendProtocolName(protoTy->castTo<ProtocolType>()->getDecl());
649+
appendListSeparator(First);
650+
}
640651
if (First)
641652
appendOperator("y");
653+
654+
if (layout.superclass) {
655+
appendType(layout.superclass);
656+
return appendOperator("XE");
657+
}
642658
return appendOperator("p");
643659
}
660+
644661
case TypeKind::UnboundGeneric:
645662
case TypeKind::Class:
646663
case TypeKind::Enum:

lib/Demangling/Demangler.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1583,6 +1583,12 @@ NodePointer Demangler::demangleSpecialType() {
15831583
case 'p':
15841584
return createType(createWithChild(Node::Kind::ExistentialMetatype,
15851585
popNode(Node::Kind::Type)));
1586+
case 'E': {
1587+
NodePointer Superclass = popNode(Node::Kind::Type);
1588+
NodePointer Protocols = demangleProtocolListType();
1589+
return createType(createWithChildren(Node::Kind::ProtocolListWithClass,
1590+
Protocols, Superclass));
1591+
}
15861592
case 'X':
15871593
case 'x': {
15881594
// SIL box types.

lib/Demangling/NodePrinter.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,7 @@ class NodePrinter {
267267
return true;
268268
return false;
269269

270+
case Node::Kind::ProtocolListWithClass:
270271
case Node::Kind::Allocator:
271272
case Node::Kind::ArgumentTuple:
272273
case Node::Kind::AssociatedTypeMetadataAccessor:
@@ -578,7 +579,8 @@ class NodePrinter {
578579

579580
static bool isExistentialType(NodePointer node) {
580581
return (node->getKind() == Node::Kind::ExistentialMetatype ||
581-
node->getKind() == Node::Kind::ProtocolList);
582+
node->getKind() == Node::Kind::ProtocolList ||
583+
node->getKind() == Node::Kind::ProtocolListWithClass);
582584
}
583585

584586
/// Print the relevant parameters and return the new index.
@@ -1388,6 +1390,16 @@ void NodePrinter::print(NodePointer pointer, bool asContext, bool suppressType)
13881390
printChildren(type_list, " & ");
13891391
return;
13901392
}
1393+
case Node::Kind::ProtocolListWithClass: {
1394+
if (pointer->getNumChildren() < 2)
1395+
return;
1396+
NodePointer protocols = pointer->getChild(0);
1397+
NodePointer superclass = pointer->getChild(1);
1398+
print(superclass);
1399+
Printer << " & ";
1400+
printChildren(protocols, " & ");
1401+
return;
1402+
}
13911403
case Node::Kind::AssociatedType:
13921404
// Don't print for now.
13931405
return;

lib/Demangling/Remangler.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,8 @@ class Remangler {
249249
mangleChildNodes(Proto);
250250
}
251251

252+
void mangleProtocolList(Node *protocols, Node *superclass);
253+
252254
bool trySubstitution(Node *node, SubstitutionEntry &entry,
253255
bool treatAsIdentifier = false);
254256
void addSubstitution(const SubstitutionEntry &entry);
@@ -1401,17 +1403,31 @@ void Remangler::mangleProtocolDescriptor(Node *node) {
14011403
Buffer << "Mp";
14021404
}
14031405

1404-
void Remangler::mangleProtocolList(Node *node) {
1405-
node = getSingleChild(node, Node::Kind::TypeList);
1406+
void Remangler::mangleProtocolList(Node *node, Node *superclass) {
14061407
bool FirstElem = true;
14071408
for (NodePointer Child : *node) {
14081409
manglePureProtocol(Child);
14091410
mangleListSeparator(FirstElem);
14101411
}
14111412
mangleEndOfList(FirstElem);
1413+
if (superclass) {
1414+
mangleType(superclass);
1415+
Buffer << "XE";
1416+
return;
1417+
}
14121418
Buffer << 'p';
14131419
}
14141420

1421+
void Remangler::mangleProtocolList(Node *node) {
1422+
auto *protocols = getSingleChild(node, Node::Kind::TypeList);
1423+
mangleProtocolList(protocols, nullptr);
1424+
}
1425+
1426+
void Remangler::mangleProtocolListWithClass(Node *node) {
1427+
mangleProtocolList(node->getChild(0),
1428+
node->getChild(1));
1429+
}
1430+
14151431
void Remangler::mangleProtocolWitness(Node *node) {
14161432
mangleChildNodes(node);
14171433
Buffer << "TW";

0 commit comments

Comments
 (0)