Skip to content

Commit 17699d4

Browse files
committed
[Metadata] Emit complete context descriptors for parents of anonymous contexts
When a (file)private entity occurs inside a generic context, we still need information about the genericity of the enclosing context to demangle to metadata. Emit complete context descriptors for parents of anonymous contexts. Fixes rdar://problem/46109026.
1 parent d4fe6e9 commit 17699d4

File tree

7 files changed

+44
-13
lines changed

7 files changed

+44
-13
lines changed

lib/Demangling/OldRemangler.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1221,6 +1221,20 @@ void Remangler::mangleEntityContext(Node *node, EntityContext &ctx) {
12211221
// Remember that we're mangling a context.
12221222
EntityContext::ManglingContextRAII raii(ctx);
12231223

1224+
// Deal with bound generic types.
1225+
switch (node->getKind()) {
1226+
case Node::Kind::BoundGenericStructure:
1227+
case Node::Kind::BoundGenericEnum:
1228+
case Node::Kind::BoundGenericClass:
1229+
case Node::Kind::BoundGenericOtherNominalType:
1230+
case Node::Kind::BoundGenericTypeAlias:
1231+
mangleAnyNominalType(node, ctx);
1232+
return;
1233+
1234+
default:
1235+
break;
1236+
}
1237+
12241238
switch (node->getKind()) {
12251239
#define NODE(ID) \
12261240
case Node::Kind::ID:
@@ -1731,6 +1745,7 @@ void Remangler::mangleExtension(Node *node, EntityContext &ctx) {
17311745
if (node->getNumChildren() == 3) {
17321746
mangleDependentGenericSignature(node->begin()[2]); // generic sig
17331747
}
1748+
17341749
mangleEntityContext(node->begin()[1], ctx); // context
17351750
}
17361751

lib/IRGen/GenDecl.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -740,7 +740,8 @@ void IRGenModule::emitRuntimeRegistration() {
740740
/// For any other kind of context, this returns an anonymous context descriptor
741741
/// for the context.
742742
ConstantReference
743-
IRGenModule::getAddrOfParentContextDescriptor(DeclContext *from) {
743+
IRGenModule::getAddrOfParentContextDescriptor(DeclContext *from,
744+
bool fromAnonymousContext) {
744745
// Some types get special treatment.
745746
if (auto Type = dyn_cast<NominalTypeDecl>(from)) {
746747
// Use a special module context if we have one.
@@ -757,7 +758,7 @@ IRGenModule::getAddrOfParentContextDescriptor(DeclContext *from) {
757758

758759
// Wrap up private types in an anonymous context for the containing file
759760
// unit so that the runtime knows they have unstable identity.
760-
if (Type->isOutermostPrivateOrFilePrivateScope())
761+
if (!fromAnonymousContext && Type->isOutermostPrivateOrFilePrivateScope())
761762
return {getAddrOfAnonymousContextDescriptor(Type),
762763
ConstantReference::Direct};
763764
}
@@ -771,15 +772,17 @@ IRGenModule::getAddrOfParentContextDescriptor(DeclContext *from) {
771772
case DeclContextKind::TopLevelCodeDecl:
772773
case DeclContextKind::Initializer:
773774
case DeclContextKind::SerializedLocal:
774-
return {getAddrOfAnonymousContextDescriptor(from),
775+
return {getAddrOfAnonymousContextDescriptor(
776+
fromAnonymousContext ? parent : from),
775777
ConstantReference::Direct};
776778

777779
case DeclContextKind::GenericTypeDecl:
778780
if (auto nomTy = dyn_cast<NominalTypeDecl>(parent)) {
779781
return {getAddrOfTypeContextDescriptor(nomTy, DontRequireMetadata),
780782
ConstantReference::Direct};
781783
}
782-
return {getAddrOfAnonymousContextDescriptor(from),
784+
return {getAddrOfAnonymousContextDescriptor(
785+
fromAnonymousContext ? parent : from),
783786
ConstantReference::Direct};
784787

785788
case DeclContextKind::ExtensionDecl: {

lib/IRGen/GenMeta.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -513,8 +513,8 @@ namespace {
513513
}
514514

515515
ConstantReference getParent() {
516-
return {IGM.getAddrOfModuleContextDescriptor(DC->getParentModule()),
517-
ConstantReference::Direct};
516+
return IGM.getAddrOfParentContextDescriptor(
517+
DC, /*fromAnonymousContext=*/true);
518518
}
519519

520520
ContextDescriptorKind getContextKind() {
@@ -565,7 +565,8 @@ namespace {
565565
}
566566

567567
ConstantReference getParent() {
568-
return IGM.getAddrOfParentContextDescriptor(Proto);
568+
return IGM.getAddrOfParentContextDescriptor(
569+
Proto, /*fromAnonymousContext=*/false);
569570
}
570571

571572
ContextDescriptorKind getContextKind() {
@@ -1014,7 +1015,8 @@ namespace {
10141015
}
10151016

10161017
ConstantReference getParent() {
1017-
return IGM.getAddrOfParentContextDescriptor(Type);
1018+
return IGM.getAddrOfParentContextDescriptor(
1019+
Type, /*fromAnonymousContext=*/false);
10181020
}
10191021

10201022
GenericSignature *getGenericSignature() {

lib/IRGen/GenProto.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1937,7 +1937,8 @@ namespace {
19371937
auto moduleContext =
19381938
normal->getDeclContext()->getModuleScopeContext();
19391939
ConstantReference moduleContextRef =
1940-
IGM.getAddrOfParentContextDescriptor(moduleContext);
1940+
IGM.getAddrOfParentContextDescriptor(moduleContext,
1941+
/*fromAnonymousContext=*/false);
19411942
B.addRelativeAddress(moduleContextRef);
19421943
}
19431944

lib/IRGen/IRGenModule.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1277,7 +1277,8 @@ private: \
12771277
ConstantInit definition = ConstantInit());
12781278
llvm::Constant *getAddrOfObjCModuleContextDescriptor();
12791279
llvm::Constant *getAddrOfClangImporterModuleContextDescriptor();
1280-
ConstantReference getAddrOfParentContextDescriptor(DeclContext *from);
1280+
ConstantReference getAddrOfParentContextDescriptor(DeclContext *from,
1281+
bool fromAnonymousContext);
12811282
llvm::Constant *getAddrOfGenericEnvironment(CanGenericSignature signature);
12821283
llvm::Constant *getAddrOfProtocolRequirementsBaseDescriptor(
12831284
ProtocolDecl *proto);

test/Runtime/associated_type_demangle_private.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,15 @@ fileprivate struct Foo {
1818
}
1919
}
2020

21+
public struct Wibble<T> { }
22+
23+
extension Wibble {
24+
fileprivate struct Inner: P {
25+
fileprivate struct Innermost { }
26+
typealias A = (Innermost, T)
27+
}
28+
}
29+
2130
func getP_A<T: P>(_: T.Type) -> Any.Type {
2231
return T.A.self
2332
}
@@ -27,6 +36,7 @@ let AssociatedTypeDemangleTests = TestSuite("AssociatedTypeDemangle")
2736

2837
AssociatedTypeDemangleTests.test("private types") {
2938
expectEqual(Foo.Inner.Innermost.self, getP_A(Foo.Inner.self))
39+
expectEqual((Wibble<Float>.Inner.Innermost, Float).self, getP_A(Wibble<Float>.Inner.self))
3040
}
3141

3242
private protocol P2 {

test/stdlib/RuntimeObjC.swift

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -760,10 +760,9 @@ RuntimeClassNamesTestSuite.test("private class nested in same-type-constrained e
760760
let util = base.asInner
761761

762762
let clas = unsafeBitCast(type(of: util), to: NSObject.self)
763-
// Name should look like _TtC1aP.*Inner
764763
let desc = clas.description
765-
expectEqual("_TtGC1a", desc.prefix(7))
766-
expectEqual("Data_", desc.suffix(5))
764+
expectEqual("_TtCE1a", desc.prefix(7))
765+
expectEqual("Inner", desc.suffix(5))
767766
}
768767

769768
runAllTests()

0 commit comments

Comments
 (0)