Skip to content

Commit 69a1311

Browse files
authored
Merge pull request #63789 from slavapestov/type-reconstruction-for-variadic-generics
Type reconstruction for variadic generics
2 parents 45edfc3 + d8f7959 commit 69a1311

File tree

15 files changed

+235
-15
lines changed

15 files changed

+235
-15
lines changed

include/swift/AST/ASTDemangler.h

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,16 @@ namespace Demangle {
3737
SWIFT_BEGIN_INLINE_NAMESPACE
3838

3939
Type getTypeForMangling(ASTContext &ctx,
40-
llvm::StringRef mangling);
40+
llvm::StringRef mangling,
41+
GenericSignature genericSig=GenericSignature());
4142

4243
TypeDecl *getTypeDeclForMangling(ASTContext &ctx,
43-
llvm::StringRef mangling);
44+
llvm::StringRef mangling,
45+
GenericSignature genericSig=GenericSignature());
4446

4547
TypeDecl *getTypeDeclForUSR(ASTContext &ctx,
46-
llvm::StringRef usr);
48+
llvm::StringRef usr,
49+
GenericSignature genericSig=GenericSignature());
4750

4851
/// An implementation of MetadataReader's BuilderType concept that
4952
/// just finds and builds things in the AST.
@@ -55,6 +58,11 @@ class ASTBuilder {
5558
/// Created lazily.
5659
DeclContext *NotionalDC = nullptr;
5760

61+
/// The generic signature for interpreting type parameters. This is used
62+
/// because the mangling for a type parameter doesn't record whether it
63+
/// is a pack or not, so we have to find it here.
64+
GenericSignature GenericSig;
65+
5866
public:
5967
using BuiltType = swift::Type;
6068
using BuiltTypeDecl = swift::GenericTypeDecl *; // nominal or type alias
@@ -66,7 +74,8 @@ class ASTBuilder {
6674

6775
static constexpr bool needsToPrecomputeParentGenericContextShapes = false;
6876

69-
explicit ASTBuilder(ASTContext &ctx) : Ctx(ctx) {}
77+
explicit ASTBuilder(ASTContext &ctx, GenericSignature genericSig)
78+
: Ctx(ctx), GenericSig(genericSig) {}
7079

7180
ASTContext &getASTContext() { return Ctx; }
7281
DeclContext *getNotionalDC();
@@ -102,6 +111,12 @@ class ASTBuilder {
102111

103112
Type createTupleType(ArrayRef<Type> eltTypes, StringRef labels);
104113

114+
Type createPackType(ArrayRef<Type> eltTypes);
115+
116+
Type createSILPackType(ArrayRef<Type> eltTypes, bool isElementAddress);
117+
118+
Type createPackExpansionType(Type patternType, Type countType);
119+
105120
Type createFunctionType(
106121
ArrayRef<Demangle::FunctionParam<Type>> params,
107122
Type output, FunctionTypeFlags flags,

include/swift/Demangling/DemangleNodes.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,8 @@ NODE(Tuple)
236236
NODE(TupleElement)
237237
NODE(TupleElementName)
238238
NODE(Pack)
239+
NODE(SILPackDirect)
240+
NODE(SILPackIndirect)
239241
NODE(PackExpansion)
240242
NODE(Type)
241243
CONTEXT_NODE(TypeSymbolicReference)

include/swift/Demangling/Demangler.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,7 @@ class Demangler : public NodeFactory {
530530
NodePointer popTuple();
531531
NodePointer popTypeList();
532532
NodePointer popPack();
533+
NodePointer popSILPack();
533534
NodePointer popProtocol();
534535
NodePointer demangleBoundGenericType();
535536
NodePointer demangleBoundGenericArgs(NodePointer nominalType,

include/swift/Demangling/TypeDecoder.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1072,6 +1072,46 @@ class TypeDecoder {
10721072
return decodeMangledType(Node->getChild(0), depth + 1,
10731073
/*forRequirement=*/false);
10741074

1075+
case NodeKind::Pack:
1076+
case NodeKind::SILPackDirect:
1077+
case NodeKind::SILPackIndirect: {
1078+
llvm::SmallVector<BuiltType, 8> elements;
1079+
1080+
for (auto &element : *Node) {
1081+
// Decode the element type.
1082+
auto elementType =
1083+
decodeMangledType(element, depth + 1, /*forRequirement=*/false);
1084+
if (elementType.isError())
1085+
return elementType;
1086+
1087+
elements.push_back(elementType.getType());
1088+
}
1089+
1090+
switch (Node->getKind()) {
1091+
case NodeKind::Pack:
1092+
return Builder.createPackType(elements);
1093+
case NodeKind::SILPackDirect:
1094+
return Builder.createSILPackType(elements, /*isElementAddress=*/false);
1095+
case NodeKind::SILPackIndirect:
1096+
return Builder.createSILPackType(elements, /*isElementAddress=*/true);
1097+
default:
1098+
llvm_unreachable("Bad kind");
1099+
}
1100+
}
1101+
1102+
case NodeKind::PackExpansion: {
1103+
if (Node->getNumChildren() < 2)
1104+
return MAKE_NODE_TYPE_ERROR(Node,
1105+
"fewer children (%zu) than required (2)",
1106+
Node->getNumChildren());
1107+
1108+
auto patternType = decodeMangledType(Node->getChild(0), depth + 1);
1109+
auto countType = decodeMangledType(Node->getChild(1), depth + 1);
1110+
1111+
return Builder.createPackExpansionType(patternType.getType(),
1112+
countType.getType());
1113+
}
1114+
10751115
case NodeKind::DependentGenericType: {
10761116
if (Node->getNumChildren() < 2)
10771117
return MAKE_NODE_TYPE_ERROR(Node,

include/swift/RemoteInspection/TypeRefBuilder.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -689,6 +689,23 @@ class TypeRefBuilder {
689689
return TupleTypeRef::create(*this, elements, std::move(labels));
690690
}
691691

692+
const TypeRef *createPackType(llvm::ArrayRef<const TypeRef *> elements) {
693+
// FIXME: Remote mirrors support for variadic generics.
694+
return nullptr;
695+
}
696+
697+
const TypeRef *createSILPackType(llvm::ArrayRef<const TypeRef *> elements,
698+
bool isElementAddress) {
699+
// FIXME: Remote mirrors support for variadic generics.
700+
return nullptr;
701+
}
702+
703+
const TypeRef *createPackExpansionType(const TypeRef *patternType,
704+
const TypeRef *countType) {
705+
// FIXME: Remote mirrors support for variadic generics.
706+
return nullptr;
707+
}
708+
692709
const FunctionTypeRef *createFunctionType(
693710
llvm::ArrayRef<remote::FunctionParam<const TypeRef *>> params,
694711
const TypeRef *result, FunctionTypeFlags flags,

lib/AST/ASTDemangler.cpp

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,36 +38,39 @@
3838
using namespace swift;
3939

4040
Type swift::Demangle::getTypeForMangling(ASTContext &ctx,
41-
StringRef mangling) {
41+
StringRef mangling,
42+
GenericSignature genericSig) {
4243
Demangle::Context Dem;
4344
auto node = Dem.demangleSymbolAsNode(mangling);
4445
if (!node)
4546
return Type();
4647

47-
ASTBuilder builder(ctx);
48+
ASTBuilder builder(ctx, genericSig);
4849
return builder.decodeMangledType(node);
4950
}
5051

5152
TypeDecl *swift::Demangle::getTypeDeclForMangling(ASTContext &ctx,
52-
StringRef mangling) {
53+
StringRef mangling,
54+
GenericSignature genericSig) {
5355
Demangle::Context Dem;
5456
auto node = Dem.demangleSymbolAsNode(mangling);
5557
if (!node)
5658
return nullptr;
5759

58-
ASTBuilder builder(ctx);
60+
ASTBuilder builder(ctx, genericSig);
5961
return builder.createTypeDecl(node);
6062
}
6163

6264
TypeDecl *swift::Demangle::getTypeDeclForUSR(ASTContext &ctx,
63-
StringRef usr) {
65+
StringRef usr,
66+
GenericSignature genericSig) {
6467
if (!usr.startswith("s:"))
6568
return nullptr;
6669

6770
std::string mangling(usr);
6871
mangling.replace(0, 2, MANGLING_PREFIX_STR);
6972

70-
return getTypeDeclForMangling(ctx, mangling);
73+
return getTypeDeclForMangling(ctx, mangling, genericSig);
7174
}
7275

7376
Type ASTBuilder::decodeMangledType(NodePointer node, bool forRequirement) {
@@ -341,6 +344,25 @@ Type ASTBuilder::createTupleType(ArrayRef<Type> eltTypes, StringRef labels) {
341344
return TupleType::get(elements, Ctx);
342345
}
343346

347+
Type ASTBuilder::createPackType(ArrayRef<Type> eltTypes) {
348+
return PackType::get(Ctx, eltTypes);
349+
}
350+
351+
Type ASTBuilder::createSILPackType(ArrayRef<Type> eltTypes,
352+
bool isElementAddress) {
353+
auto extInfo = SILPackType::ExtInfo(isElementAddress);
354+
355+
SmallVector<CanType, 4> elements;
356+
for (auto eltType : eltTypes)
357+
elements.push_back(eltType->getCanonicalType());
358+
359+
return SILPackType::get(Ctx, extInfo, elements);
360+
}
361+
362+
Type ASTBuilder::createPackExpansionType(Type patternType, Type countType) {
363+
return PackExpansionType::get(patternType, countType);
364+
}
365+
344366
Type ASTBuilder::createFunctionType(
345367
ArrayRef<Demangle::FunctionParam<Type>> params,
346368
Type output, FunctionTypeFlags flags,
@@ -683,7 +705,23 @@ Type ASTBuilder::createMetatypeType(Type instance,
683705

684706
Type ASTBuilder::createGenericTypeParameterType(unsigned depth,
685707
unsigned index) {
686-
return GenericTypeParamType::get(/*isParameterPack*/ false, depth, index, Ctx);
708+
// If we have a generic signature, find the parameter with the matching
709+
// depth and index and return it, to get the correct value for the
710+
// isParameterPack() bit.
711+
if (GenericSig) {
712+
for (auto paramTy : GenericSig.getGenericParams()) {
713+
if (paramTy->getDepth() == depth && paramTy->getIndex() == index) {
714+
return paramTy;
715+
}
716+
}
717+
718+
return Type();
719+
}
720+
721+
// Otherwise, just assume we're not working with variadic generics.
722+
// FIXME: Should we always require a generic signature in this case?
723+
return GenericTypeParamType::get(/*isParameterPack*/ false,
724+
depth, index, Ctx);
687725
}
688726

689727
Type ASTBuilder::createDependentMemberType(StringRef member,
@@ -973,6 +1011,13 @@ LayoutConstraint ASTBuilder::getLayoutConstraintWithSizeAlign(
9731011
CanGenericSignature ASTBuilder::demangleGenericSignature(
9741012
NominalTypeDecl *nominalDecl,
9751013
NodePointer node) {
1014+
// The type parameters appearing in the signature's requirements are not
1015+
// notionally part of our current generic signature.
1016+
//
1017+
// FIXME: Fix this to support variadic generics.
1018+
llvm::SaveAndRestore<GenericSignature> savedSignature(
1019+
GenericSig, GenericSignature());
1020+
9761021
SmallVector<Requirement, 2> requirements;
9771022

9781023
decodeRequirement<BuiltType, BuiltRequirement, BuiltLayoutConstraint,

lib/Demangling/Demangler.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1564,6 +1564,38 @@ NodePointer Demangler::popPack() {
15641564
return createType(Root);
15651565
}
15661566

1567+
NodePointer Demangler::popSILPack() {
1568+
NodePointer Root;
1569+
1570+
switch (nextChar()) {
1571+
case 'd':
1572+
Root = createNode(Node::Kind::SILPackDirect);
1573+
break;
1574+
1575+
case 'i':
1576+
Root = createNode(Node::Kind::SILPackIndirect);
1577+
break;
1578+
1579+
default:
1580+
return nullptr;
1581+
}
1582+
1583+
if (!popNode(Node::Kind::EmptyList)) {
1584+
bool firstElem = false;
1585+
do {
1586+
firstElem = (popNode(Node::Kind::FirstElementMarker) != nullptr);
1587+
NodePointer Ty = popNode(Node::Kind::Type);
1588+
if (!Ty)
1589+
return nullptr;
1590+
Root->addChild(Ty, *this);
1591+
} while (!firstElem);
1592+
1593+
Root->reverseChildren();
1594+
}
1595+
1596+
return createType(Root);
1597+
}
1598+
15671599
NodePointer Demangler::popTypeList() {
15681600
NodePointer Root = createNode(Node::Kind::TypeList);
15691601

@@ -2364,6 +2396,8 @@ NodePointer Demangler::demangleArchetype() {
23642396
}
23652397
case 'P':
23662398
return popPack();
2399+
case 'S':
2400+
return popSILPack();
23672401
default:
23682402
return nullptr;
23692403
}

lib/Demangling/NodePrinter.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,8 @@ class NodePrinter {
308308
case Node::Kind::Module:
309309
case Node::Kind::Tuple:
310310
case Node::Kind::Pack:
311+
case Node::Kind::SILPackDirect:
312+
case Node::Kind::SILPackIndirect:
311313
case Node::Kind::ConstrainedExistential:
312314
case Node::Kind::ConstrainedExistentialRequirementList:
313315
case Node::Kind::ConstrainedExistentialSelf:
@@ -1511,9 +1513,17 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth,
15111513
Printer << "}";
15121514
return nullptr;
15131515
}
1516+
case Node::Kind::SILPackDirect:
1517+
case Node::Kind::SILPackIndirect: {
1518+
Printer << (kind == Node::Kind::SILPackDirect ? "@direct" : "@indirect");
1519+
Printer << " Pack{";
1520+
printChildren(Node, depth, ", ");
1521+
Printer << "}";
1522+
return nullptr;
1523+
}
15141524
case Node::Kind::PackExpansion: {
1525+
Printer << "repeat ";
15151526
print(Node->getChild(0), depth + 1);
1516-
Printer << "...";
15171527
return nullptr;
15181528
}
15191529
case Node::Kind::ReturnType:

lib/Demangling/OldRemangler.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1911,6 +1911,14 @@ ManglingError Remangler::manglePack(Node *node, unsigned depth) {
19111911
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
19121912
}
19131913

1914+
ManglingError Remangler::mangleSILPackDirect(Node *node, unsigned depth) {
1915+
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
1916+
}
1917+
1918+
ManglingError Remangler::mangleSILPackIndirect(Node *node, unsigned depth) {
1919+
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
1920+
}
1921+
19141922
ManglingError Remangler::manglePackExpansion(Node *node, unsigned depth) {
19151923
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
19161924
}

lib/Demangling/Remangler.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2278,6 +2278,18 @@ ManglingError Remangler::manglePack(Node *node, unsigned depth) {
22782278
return ManglingError::Success;
22792279
}
22802280

2281+
ManglingError Remangler::mangleSILPackDirect(Node *node, unsigned depth) {
2282+
RETURN_IF_ERROR(mangleTypeList(node, depth + 1));
2283+
Buffer << "QSd";
2284+
return ManglingError::Success;
2285+
}
2286+
2287+
ManglingError Remangler::mangleSILPackIndirect(Node *node, unsigned depth) {
2288+
RETURN_IF_ERROR(mangleTypeList(node, depth + 1));
2289+
Buffer << "QSi";
2290+
return ManglingError::Success;
2291+
}
2292+
22812293
ManglingError Remangler::manglePackExpansion(Node *node, unsigned depth) {
22822294
RETURN_IF_ERROR(mangleChildNodes(node, depth + 1));
22832295
Buffer << "Qp";

lib/IRGen/IRGenDebugInfo.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -907,11 +907,13 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
907907
!Ty->getASTContext().LangOpts.EnableCXXInterop) {
908908
// Make sure we can reconstruct mangled types for the debugger.
909909
auto &Ctx = Ty->getASTContext();
910-
Type Reconstructed = Demangle::getTypeForMangling(Ctx, Result);
910+
Type Reconstructed = Demangle::getTypeForMangling(Ctx, Result, Sig);
911911
if (!Reconstructed) {
912912
llvm::errs() << "Failed to reconstruct type for " << Result << "\n";
913913
llvm::errs() << "Original type:\n";
914914
Ty->dump(llvm::errs());
915+
if (Sig)
916+
llvm::errs() << "Generic signature: " << Sig << "\n";
915917
abort();
916918
} else if (!Reconstructed->isEqual(Ty) &&
917919
// FIXME: Some existential types are reconstructed without
@@ -924,6 +926,8 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
924926
Ty->dump(llvm::errs());
925927
llvm::errs() << "Reconstructed type:\n";
926928
Reconstructed->dump(llvm::errs());
929+
if (Sig)
930+
llvm::errs() << "Generic signature: " << Sig << "\n";
927931
abort();
928932
}
929933
}

lib/RemoteAST/RemoteAST.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,7 @@ class RemoteASTContextConcreteImpl final : public RemoteASTContextImpl {
432432
public:
433433
RemoteASTContextConcreteImpl(std::shared_ptr<MemoryReader> &&reader,
434434
ASTContext &ctx)
435-
: Reader(std::move(reader), ctx) {}
435+
: Reader(std::move(reader), ctx, GenericSignature()) {}
436436

437437
Result<Type> getTypeForRemoteTypeMetadata(RemoteAddress metadata,
438438
bool skipArtificial) override {

0 commit comments

Comments
 (0)