Skip to content

Commit d789415

Browse files
authored
Merge pull request #61986 from slavapestov/pack-sil-type-lowering
Preliminary mangling and SIL type lowering for PackType and PackExpansionType
2 parents b2e34b2 + 8379601 commit d789415

File tree

14 files changed

+428
-68
lines changed

14 files changed

+428
-68
lines changed

docs/ABI/Mangling.rst

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -637,7 +637,6 @@ Types
637637
METATYPE-REPR ::= 'T' // Thick metatype representation
638638
METATYPE-REPR ::= 'o' // ObjC metatype representation
639639

640-
type ::= archetype
641640
type ::= associated-type
642641
type ::= any-generic-type
643642
type ::= protocol-list 'p' // existential type
@@ -654,6 +653,12 @@ Types
654653
type ::= assoc-type-list 'QY' GENERIC-PARAM-INDEX // associated type at depth
655654
type ::= assoc-type-list 'QZ' // shortcut for 'QYz'
656655
656+
type ::= pattern-type count-type 'Qp' // pack expansion type
657+
type ::= pack-element-list 'QP' // pack type
658+
659+
pack-element-list ::= type '_' type*
660+
pack-element-list ::= empty-list
661+
657662
#if SWIFT_RUNTIME_VERSION >= 5.2
658663
type ::= type assoc-type-name 'Qx' // associated type relative to base `type`
659664
type ::= type assoc-type-list 'QX' // associated type relative to base `type`
@@ -668,11 +673,8 @@ Types
668673

669674
assoc-type-list ::= assoc-type-name '_' assoc-type-name*
670675

671-
archetype ::= associated-type
672-
673676
associated-type ::= substitution
674-
associated-type ::= protocol 'QP' // self type of protocol
675-
associated-type ::= archetype identifier 'Qa' // associated type
677+
associated-type ::= type identifier 'Qa' // associated type
676678

677679
assoc-type-name ::= identifier // associated type name without protocol
678680
assoc-type-name ::= identifier protocol 'P' //

include/swift/Demangling/DemangleNodes.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,8 @@ NODE(ThinFunctionType)
227227
NODE(Tuple)
228228
NODE(TupleElement)
229229
NODE(TupleElementName)
230+
NODE(Pack)
231+
NODE(PackExpansion)
230232
NODE(Type)
231233
CONTEXT_NODE(TypeSymbolicReference)
232234
CONTEXT_NODE(TypeAlias)

include/swift/Demangling/Demangler.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,7 @@ class Demangler : public NodeFactory {
518518
NodePointer popFunctionParamLabels(NodePointer FuncType);
519519
NodePointer popTuple();
520520
NodePointer popTypeList();
521+
NodePointer popPack();
521522
NodePointer popProtocol();
522523
NodePointer demangleBoundGenericType();
523524
NodePointer demangleBoundGenericArgs(NodePointer nominalType,

include/swift/SIL/AbstractionPattern.h

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1255,6 +1255,64 @@ class AbstractionPattern {
12551255
llvm_unreachable("bad kind");
12561256
}
12571257

1258+
/// Is the given pack type a valid substitution of this abstraction
1259+
/// pattern?
1260+
bool matchesPack(CanPackType substType);
1261+
1262+
bool isPack() const {
1263+
switch (getKind()) {
1264+
case Kind::Invalid:
1265+
llvm_unreachable("querying invalid abstraction pattern!");
1266+
case Kind::Opaque:
1267+
case Kind::PartialCurriedObjCMethodType:
1268+
case Kind::CurriedObjCMethodType:
1269+
case Kind::CFunctionAsMethodType:
1270+
case Kind::CurriedCFunctionAsMethodType:
1271+
case Kind::PartialCurriedCFunctionAsMethodType:
1272+
case Kind::ObjCMethodType:
1273+
case Kind::CXXMethodType:
1274+
case Kind::CurriedCXXMethodType:
1275+
case Kind::PartialCurriedCXXMethodType:
1276+
case Kind::OpaqueFunction:
1277+
case Kind::OpaqueDerivativeFunction:
1278+
case Kind::ObjCCompletionHandlerArgumentsType:
1279+
case Kind::Tuple:
1280+
case Kind::ClangType:
1281+
return false;
1282+
case Kind::Type:
1283+
case Kind::Discard:
1284+
return isa<PackType>(getType());
1285+
}
1286+
llvm_unreachable("bad kind");
1287+
}
1288+
1289+
size_t getNumPackElements() const {
1290+
switch (getKind()) {
1291+
case Kind::Invalid:
1292+
llvm_unreachable("querying invalid abstraction pattern!");
1293+
case Kind::Opaque:
1294+
case Kind::PartialCurriedObjCMethodType:
1295+
case Kind::CurriedObjCMethodType:
1296+
case Kind::CFunctionAsMethodType:
1297+
case Kind::CurriedCFunctionAsMethodType:
1298+
case Kind::PartialCurriedCFunctionAsMethodType:
1299+
case Kind::ObjCMethodType:
1300+
case Kind::CXXMethodType:
1301+
case Kind::CurriedCXXMethodType:
1302+
case Kind::PartialCurriedCXXMethodType:
1303+
case Kind::OpaqueFunction:
1304+
case Kind::OpaqueDerivativeFunction:
1305+
case Kind::ObjCCompletionHandlerArgumentsType:
1306+
case Kind::Tuple:
1307+
case Kind::ClangType:
1308+
llvm_unreachable("pattern is not a pack");
1309+
case Kind::Type:
1310+
case Kind::Discard:
1311+
return cast<PackType>(getType())->getNumElements();
1312+
}
1313+
llvm_unreachable("bad kind");
1314+
}
1315+
12581316
/// Given that the value being abstracted is a move only type, return the
12591317
/// abstraction pattern with the move only bit removed.
12601318
AbstractionPattern removingMoveOnlyWrapper() const;
@@ -1264,9 +1322,21 @@ class AbstractionPattern {
12641322
AbstractionPattern addingMoveOnlyWrapper() const;
12651323

12661324
/// Given that the value being abstracted is a tuple type, return
1267-
/// the abstraction pattern for its object type.
1325+
/// the abstraction pattern for an element type.
12681326
AbstractionPattern getTupleElementType(unsigned index) const;
12691327

1328+
/// Given that the value being abstracted is a pack type, return
1329+
/// the abstraction pattern for an element type.
1330+
AbstractionPattern getPackElementType(unsigned index) const;
1331+
1332+
/// Give that the value being abstracted is a pack expansion type, return the
1333+
/// underlying pattern type.
1334+
AbstractionPattern getPackExpansionPatternType() const;
1335+
1336+
/// Give that the value being abstracted is a pack expansion type, return the
1337+
/// underlying count type.
1338+
AbstractionPattern getPackExpansionCountType() const;
1339+
12701340
/// Given that the value being abstracted is a function, return the
12711341
/// abstraction pattern for its result type.
12721342
AbstractionPattern getFunctionResultType() const;

lib/AST/ASTMangler.cpp

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1235,12 +1235,29 @@ void ASTMangler::appendType(Type type, GenericSignature sig,
12351235
return appendAnyGenericType(decl);
12361236
}
12371237

1238-
case TypeKind::Pack:
1239-
case TypeKind::PackExpansion:
1240-
assert(DWARFMangling && "sugared types are only legal for the debugger");
1241-
appendOperator("XSP");
1242-
llvm_unreachable("Unimplemented");
1238+
case TypeKind::PackExpansion: {
1239+
auto expansionTy = cast<PackExpansionType>(tybase);
1240+
appendType(expansionTy->getPatternType(), sig, forDecl);
1241+
appendType(expansionTy->getCountType(), sig, forDecl);
1242+
appendOperator("Qp");
12431243
return;
1244+
}
1245+
1246+
case TypeKind::Pack: {
1247+
auto packTy = cast<PackType>(tybase);
1248+
1249+
if (packTy->getNumElements() == 0)
1250+
appendOperator("y");
1251+
else {
1252+
bool firstField = true;
1253+
for (auto element : packTy->getElementTypes()) {
1254+
appendType(element, sig, forDecl);
1255+
appendListSeparator(firstField);
1256+
}
1257+
}
1258+
appendOperator("QP");
1259+
return;
1260+
}
12441261

12451262
case TypeKind::Paren:
12461263
assert(DWARFMangling && "sugared types are only legal for the debugger");

lib/AST/Type.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,20 @@ static bool isLegalSILType(CanType type) {
655655
return true;
656656
}
657657

658+
// Packs are legal if all their elements are legal.
659+
if (auto packType = dyn_cast<PackType>(type)) {
660+
for (auto eltType : packType.getElementTypes()) {
661+
if (!isLegalSILType(eltType)) return false;
662+
}
663+
return true;
664+
}
665+
666+
// Pack expansions are legal if all their pattern and count types are legal.
667+
if (auto packExpansionType = dyn_cast<PackExpansionType>(type)) {
668+
return (isLegalSILType(packExpansionType.getPatternType()) &&
669+
isLegalSILType(packExpansionType.getCountType()));
670+
}
671+
658672
// Optionals are legal if their object type is legal.
659673
if (auto objectType = type.getOptionalObjectType()) {
660674
return isLegalSILType(objectType);

lib/Demangling/Demangler.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1506,6 +1506,24 @@ NodePointer Demangler::popTuple() {
15061506
return createType(Root);
15071507
}
15081508

1509+
NodePointer Demangler::popPack() {
1510+
NodePointer Root = createNode(Node::Kind::Pack);
1511+
1512+
if (!popNode(Node::Kind::EmptyList)) {
1513+
bool firstElem = false;
1514+
do {
1515+
firstElem = (popNode(Node::Kind::FirstElementMarker) != nullptr);
1516+
NodePointer Ty = popNode(Node::Kind::Type);
1517+
if (!Ty)
1518+
return nullptr;
1519+
Root->addChild(Ty, *this);
1520+
} while (!firstElem);
1521+
1522+
Root->reverseChildren();
1523+
}
1524+
return createType(Root);
1525+
}
1526+
15091527
NodePointer Demangler::popTypeList() {
15101528
NodePointer Root = createNode(Node::Kind::TypeList);
15111529

@@ -2290,6 +2308,16 @@ NodePointer Demangler::demangleArchetype() {
22902308
addSubstitution(T);
22912309
return T;
22922310
}
2311+
case 'p': {
2312+
NodePointer CountTy = popTypeAndGetChild();
2313+
NodePointer PatternTy = popTypeAndGetChild();
2314+
NodePointer PackExpansionTy = createType(
2315+
createWithChildren(Node::Kind::PackExpansion, PatternTy, CountTy));
2316+
addSubstitution(PackExpansionTy);
2317+
return PackExpansionTy;
2318+
}
2319+
case 'P':
2320+
return popPack();
22932321
default:
22942322
return nullptr;
22952323
}

lib/Demangling/NodePrinter.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,7 @@ class NodePrinter {
307307
case Node::Kind::MetatypeRepresentation:
308308
case Node::Kind::Module:
309309
case Node::Kind::Tuple:
310+
case Node::Kind::Pack:
310311
case Node::Kind::ConstrainedExistential:
311312
case Node::Kind::ConstrainedExistentialRequirementList:
312313
case Node::Kind::ConstrainedExistentialSelf:
@@ -337,6 +338,7 @@ class NodePrinter {
337338
case Node::Kind::ProtocolListWithAnyObject:
338339
return Node->getChild(0)->getChild(0)->getNumChildren() == 0;
339340

341+
case Node::Kind::PackExpansion:
340342
case Node::Kind::ProtocolListWithClass:
341343
case Node::Kind::AccessorFunctionReference:
342344
case Node::Kind::Allocator:
@@ -1463,6 +1465,17 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth,
14631465
case Node::Kind::TupleElementName:
14641466
Printer << Node->getText() << ": ";
14651467
return nullptr;
1468+
case Node::Kind::Pack: {
1469+
Printer << "Pack{";
1470+
printChildren(Node, depth, ", ");
1471+
Printer << "}";
1472+
return nullptr;
1473+
}
1474+
case Node::Kind::PackExpansion: {
1475+
print(Node->getChild(0), depth + 1);
1476+
Printer << "...";
1477+
return nullptr;
1478+
}
14661479
case Node::Kind::ReturnType:
14671480
if (Node->getNumChildren() == 0)
14681481
Printer << " -> " << Node->getText();

lib/Demangling/OldRemangler.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1860,6 +1860,14 @@ ManglingError Remangler::mangleTupleElementName(Node *node, unsigned depth) {
18601860
return mangleIdentifier(node->getText(), OperatorKind::NotOperator);
18611861
}
18621862

1863+
ManglingError Remangler::manglePack(Node *node, unsigned depth) {
1864+
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
1865+
}
1866+
1867+
ManglingError Remangler::manglePackExpansion(Node *node, unsigned depth) {
1868+
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
1869+
}
1870+
18631871
ManglingError Remangler::mangleDependentGenericType(Node *node,
18641872
unsigned depth) {
18651873
Buffer << 'u';

lib/Demangling/Remangler.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2243,6 +2243,18 @@ ManglingError Remangler::mangleTuple(Node *node, unsigned depth) {
22432243
return ManglingError::Success;
22442244
}
22452245

2246+
ManglingError Remangler::manglePack(Node *node, unsigned depth) {
2247+
RETURN_IF_ERROR(mangleTypeList(node, depth + 1));
2248+
Buffer << "QP";
2249+
return ManglingError::Success;
2250+
}
2251+
2252+
ManglingError Remangler::manglePackExpansion(Node *node, unsigned depth) {
2253+
RETURN_IF_ERROR(mangleChildNodes(node, depth + 1));
2254+
Buffer << "Qp";
2255+
return ManglingError::Success;
2256+
}
2257+
22462258
ManglingError Remangler::mangleNumber(Node *node, unsigned depth) {
22472259
mangleIndex(node->getIndex());
22482260
return ManglingError::Success;

0 commit comments

Comments
 (0)