Skip to content

Commit 4855621

Browse files
committed
ASTDemangler: Pass down a generic signature so that we can reconstruct pack generic parameters
1 parent d15c592 commit 4855621

File tree

6 files changed

+67
-14
lines changed

6 files changed

+67
-14
lines changed

include/swift/AST/ASTDemangler.h

Lines changed: 13 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();

lib/AST/ASTDemangler.cpp

Lines changed: 33 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) {
@@ -683,7 +686,23 @@ Type ASTBuilder::createMetatypeType(Type instance,
683686

684687
Type ASTBuilder::createGenericTypeParameterType(unsigned depth,
685688
unsigned index) {
686-
return GenericTypeParamType::get(/*isParameterPack*/ false, depth, index, Ctx);
689+
// If we have a generic signature, find the parameter with the matching
690+
// depth and index and return it, to get the correct value for the
691+
// isParameterPack() bit.
692+
if (GenericSig) {
693+
for (auto paramTy : GenericSig.getGenericParams()) {
694+
if (paramTy->getDepth() == depth && paramTy->getIndex() == index) {
695+
return paramTy;
696+
}
697+
}
698+
699+
return Type();
700+
}
701+
702+
// Otherwise, just assume we're not working with variadic generics.
703+
// FIXME: Should we always require a generic signature in this case?
704+
return GenericTypeParamType::get(/*isParameterPack*/ false,
705+
depth, index, Ctx);
687706
}
688707

689708
Type ASTBuilder::createDependentMemberType(StringRef member,
@@ -973,6 +992,13 @@ LayoutConstraint ASTBuilder::getLayoutConstraintWithSizeAlign(
973992
CanGenericSignature ASTBuilder::demangleGenericSignature(
974993
NominalTypeDecl *nominalDecl,
975994
NodePointer node) {
995+
// The type parameters appearing in the signature's requirements are not
996+
// notionally part of our current generic signature.
997+
//
998+
// FIXME: Fix this to support variadic generics.
999+
llvm::SaveAndRestore<GenericSignature> savedSignature(
1000+
GenericSig, GenericSignature());
1001+
9761002
SmallVector<Requirement, 2> requirements;
9771003

9781004
decodeRequirement<BuiltType, BuiltRequirement, BuiltLayoutConstraint,

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 {

lib/Sema/TypeCheckType.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3478,7 +3478,7 @@ TypeResolver::resolveOpaqueReturnType(TypeRepr *repr, StringRef mangledName,
34783478
}
34793479
if (definingDeclNode->getKind() == Node::Kind::Global)
34803480
definingDeclNode = definingDeclNode->getChild(0);
3481-
ASTBuilder builder(getASTContext());
3481+
ASTBuilder builder(getASTContext(), GenericSignature());
34823482
auto opaqueNode =
34833483
builder.getNodeFactory().createNode(Node::Kind::OpaqueReturnTypeOf);
34843484
opaqueNode->addChild(definingDeclNode, builder.getNodeFactory());
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// RUN: %target-swift-frontend -emit-ir -g %s
2+
3+
// Make sure we don't get the generic signature of the extension
4+
// (<T, U where T: Equatable, U: Equatable>) mixed up with the
5+
// generic signature of our function foo() (<T where T: Equatable>).
6+
7+
public struct G<T, U> {}
8+
9+
extension G where T: Equatable, U: Equatable {
10+
public struct Nested {}
11+
}
12+
13+
public func foo<T>(_: G<T, T>.Nested) {
14+
}

0 commit comments

Comments
 (0)