Skip to content

Commit 69f769f

Browse files
authored
Merge pull request swiftlang#64808 from tshortli/unavailable-opaque-type-optimization
IRGen: Opaque type descriptor and nested type fixes for `-unavailable-decl-optimization`
2 parents 6e695bf + cfe9ddd commit 69f769f

11 files changed

+282
-179
lines changed

lib/AST/Availability.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,9 @@ AvailabilityInference::parentDeclForInferredAvailability(const Decl *D) {
184184
if (auto *PBD = dyn_cast<PatternBindingDecl>(D))
185185
return PBD->getAnchoringVarDecl(0);
186186

187+
if (auto *OTD = dyn_cast<OpaqueTypeDecl>(D))
188+
return OTD->getNamingDecl();
189+
187190
// Clang decls may be inaccurately parented rdar://53956555
188191
if (D->hasClangNode())
189192
return nullptr;

lib/AST/Decl.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1100,6 +1100,8 @@ AvailabilityContext Decl::getAvailabilityForLinkage() const {
11001100
return *containingContext;
11011101
}
11021102

1103+
// FIXME: Adopt AvailabilityInference::parentDeclForInferredAvailability()
1104+
// here instead of duplicating the logic.
11031105
if (auto *accessor = dyn_cast<AccessorDecl>(this))
11041106
return accessor->getStorage()->getAvailabilityForLinkage();
11051107

lib/IRGen/GenDecl.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5489,6 +5489,9 @@ Address IRGenModule::getAddrOfEnumCase(EnumElementDecl *Case,
54895489

54905490
void IRGenModule::emitNestedTypeDecls(DeclRange members) {
54915491
for (Decl *member : members) {
5492+
if (Lowering::shouldSkipLowering(member))
5493+
continue;
5494+
54925495
member->visitAuxiliaryDecls([&](Decl *decl) {
54935496
emitNestedTypeDecls({decl, nullptr});
54945497
});

lib/IRGen/GenStruct.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1572,6 +1572,9 @@ void IRGenModule::emitStructDecl(StructDecl *st) {
15721572
}
15731573

15741574
void IRGenModule::maybeEmitOpaqueTypeDecl(OpaqueTypeDecl *opaque) {
1575+
if (Lowering::shouldSkipLowering(opaque))
1576+
return;
1577+
15751578
if (IRGen.Opts.EnableAnonymousContextMangledNames) {
15761579
// If we're emitting anonymous context mangled names for debuggability,
15771580
// then emit all opaque type descriptors and make them runtime-discoverable

test/IRGen/unavailable_decl_optimization.swift

Lines changed: 0 additions & 179 deletions
Original file line numberDiff line numberDiff line change
@@ -13,182 +13,3 @@ public let globalConstant = true
1313
// CHECK-STRIP-NOT: s4Test15unavailableFuncyyF
1414
@available(*, unavailable)
1515
public func unavailableFunc() {}
16-
17-
@available(*, unavailable)
18-
public struct UnavailableStruct<T> {
19-
// CHECK-NO-STRIP: s4Test17UnavailableStructV8propertyxvg
20-
// CHECK-NO-STRIP: s4Test17UnavailableStructV8propertyxvs
21-
// CHECK-NO-STRIP: s4Test17UnavailableStructV8propertyxvM
22-
// CHECK-STRIP-NOT: s4Test17UnavailableStructV8propertyxvg
23-
// CHECK-STRIP-NOT: s4Test17UnavailableStructV8propertyxvs
24-
// CHECK-STRIP-NOT: s4Test17UnavailableStructV8propertyxvM
25-
public var property: T
26-
27-
// CHECK-NO-STRIP: s4Test17UnavailableStructVyACyxGxcfC
28-
// CHECK-NO-STRIP: s4Test17UnavailableStructVMa
29-
// CHECK-STRIP-NOT: s4Test17UnavailableStructVyACyxGxcfC
30-
// CHECK-STRIP-NOT: s4Test17UnavailableStructVMa
31-
public init(_ t: T) {
32-
self.property = t
33-
}
34-
35-
// CHECK-NO-STRIP: s4Test17UnavailableStructV6methodyyF
36-
// CHECK-STRIP-NOT: s4Test17UnavailableStructV6methodyyF
37-
public func method() {}
38-
}
39-
40-
@available(*, unavailable)
41-
extension UnavailableStruct {
42-
// CHECK-NO-STRIP: s4Test17UnavailableStructV15extensionMethodyyF
43-
// CHECK-STRIP-NOT: s4Test17UnavailableStructV15extensionMethodyyF
44-
public func extensionMethod() {}
45-
}
46-
47-
@available(*, unavailable)
48-
public enum UnavailableEnum {
49-
case a, b
50-
51-
// CHECK-NO-STRIP: s4Test15UnavailableEnumO6methodyyF
52-
// CHECK-STRIP-NOT: s4Test15UnavailableEnumO6methodyyF
53-
public func method() {}
54-
55-
// CHECK-NO-STRIP: s4Test15UnavailableEnumO21__derived_enum_equalsySbAC_ACtFZ
56-
// CHECK-NO-STRIP: s4Test15UnavailableEnumO4hash4intoys6HasherVz_tF
57-
// CHECK-NO-STRIP: s4Test15UnavailableEnumO9hashValueSivg
58-
// CHECK-STRIP-NOT: s4Test15UnavailableEnumO21__derived_enum_equalsySbAC_ACtFZ
59-
// CHECK-STRIP-NOT: s4Test15UnavailableEnumO4hash4intoys6HasherVz_tF
60-
// CHECK-STRIP-NOT: s4Test15UnavailableEnumO9hashValueSivg
61-
}
62-
63-
@available(*, unavailable)
64-
public class UnavailableClass<T> {
65-
// CHECK-NO-STRIP: s4Test16UnavailableClassC8propertyxvg
66-
// CHECK-NO-STRIP: s4Test16UnavailableClassC8propertyxvs
67-
// CHECK-NO-STRIP: s4Test16UnavailableClassC8propertyxvM
68-
// CHECK-STRIP-NOT: s4Test16UnavailableClassC8propertyxvg
69-
// CHECK-STRIP-NOT: s4Test16UnavailableClassC8propertyxvs
70-
// CHECK-STRIP-NOT: s4Test16UnavailableClassC8propertyxvM
71-
public var property: T
72-
73-
// CHECK-NO-STRIP: s4Test16UnavailableClassCyACyxGxcfC
74-
// CHECK-NO-STRIP: s4Test16UnavailableClassCyACyxGxcfc
75-
// CHECK-STRIP-NOT: s4Test16UnavailableClassCyACyxGxcfC
76-
// CHECK-STRIP-NOT: s4Test16UnavailableClassCyACyxGxcfc
77-
public init(_ t: T) {
78-
self.property = t
79-
}
80-
81-
// CHECK-NO-STRIP: s4Test16UnavailableClassCfd
82-
// CHECK-NO-STRIP: s4Test16UnavailableClassCfD
83-
// CHECK-STRIP-NOT: s4Test16UnavailableClassCfd
84-
// CHECK-STRIP-NOT: s4Test16UnavailableClassCfD
85-
deinit {}
86-
}
87-
88-
public struct S<T> {
89-
// CHECK-NO-STRIP: s4Test1SV19unavailablePropertyxvg
90-
// CHECK-NO-STRIP: s4Test1SV19unavailablePropertyxvs
91-
// CHECK-NO-STRIP: s4Test1SV19unavailablePropertyxvM
92-
// CHECK-STRIP-NOT: s4Test1SV19unavailablePropertyxvg
93-
// CHECK-STRIP-NOT: s4Test1SV19unavailablePropertyxvs
94-
// CHECK-STRIP-NOT: s4Test1SV19unavailablePropertyxvM
95-
@available(*, unavailable)
96-
public var unavailableProperty: T
97-
98-
// CHECK-NO-STRIP: s4Test1SVyACyxGxcfC
99-
// CHECK-STRIP-NOT: s4Test1SVyACyxGxcfC
100-
@available(*, unavailable)
101-
public init(_ t: T) { fatalError() }
102-
103-
// CHECK-NO-STRIP: s4Test1SV17unavailableMethodyyF
104-
// CHECK-STRIP-NOT: s4Test1SV17unavailableMethodyyF
105-
@available(*, unavailable)
106-
public func unavailableMethod() {}
107-
}
108-
109-
@available(*, unavailable)
110-
extension S {
111-
// CHECK-NO-STRIP: s4Test1SV28methodInUnavailableExtensionyyF
112-
// CHECK-STRIP-NOT: s4Test1SV28methodInUnavailableExtensionyyF
113-
public func methodInUnavailableExtension() {}
114-
}
115-
116-
public enum E {
117-
case a
118-
119-
@available(*, unavailable)
120-
case b
121-
122-
// CHECK-NO-STRIP: s4Test1EO17unavailableMethodyyF
123-
// CHECK-STRIP-NOT: s4Test1EO17unavailableMethodyyF
124-
@available(*, unavailable)
125-
public func unavailableMethod() {}
126-
}
127-
128-
public class C<T> {
129-
// CHECK-NO-STRIP: s4Test1CC19unavailablePropertyxvg
130-
// CHECK-NO-STRIP: s4Test1CC19unavailablePropertyxvs
131-
// CHECK-NO-STRIP: s4Test1CC19unavailablePropertyxvM
132-
// CHECK-STRIP-NOT: s4Test1CC19unavailablePropertyxvg
133-
// CHECK-STRIP-NOT: s4Test1CC19unavailablePropertyxvs
134-
// CHECK-STRIP-NOT: s4Test1CC19unavailablePropertyxvM
135-
@available(*, unavailable)
136-
public var unavailableProperty: T
137-
138-
// CHECK-NO-STRIP: s4Test1CCyACyxGxcfC
139-
// CHECK-NO-STRIP: s4Test1CCyACyxGxcfc
140-
// CHECK-STRIP-NOT: s4Test1CCyACyxGxcfC
141-
// CHECK-STRIP-NOT: s4Test1CCyACyxGxcfc
142-
@available(*, unavailable)
143-
public init(_ t: T) { fatalError() }
144-
145-
// CHECK: s4Test1CCfd
146-
// CHECK: s4Test1CCfD
147-
deinit {}
148-
}
149-
150-
public protocol P {
151-
func requirement()
152-
}
153-
154-
@available(*, unavailable)
155-
extension S: P {
156-
// CHECK-NO-STRIP: s4Test1SV11requirementyyF
157-
// CHECK-STRIP-NOT: s4Test1SV11requirementyyF
158-
public func requirement() {}
159-
}
160-
161-
// CHECK-NO-STRIP: s4Test29unavailableFuncWithNestedTypeyyF
162-
// CHECK-STRIP-NOT: s4Test29unavailableFuncWithNestedTypeyyF
163-
@available(*, unavailable)
164-
public func unavailableFuncWithNestedType() {
165-
struct Nested {
166-
// s4Test29unavailableFuncWithNestedTypeyyF0E0L_V6methodyyF
167-
public func method() {}
168-
}
169-
}
170-
171-
// MARK: -
172-
173-
// MARK: UnavailableEnum
174-
175-
// CHECK-NO-STRIP: s4Test15UnavailableEnumOwug
176-
// CHECK-STRIP-NOT: s4Test15UnavailableEnumOwug
177-
178-
// CHECK-NO-STRIP: s4Test15UnavailableEnumOMa
179-
// CHECK-STRIP-NOT: s4Test15UnavailableEnumOMa
180-
181-
// MARK: UnavailableClass
182-
183-
// CHECK-NO-STRIP: s4Test16UnavailableClassCMa
184-
// CHECK-STRIP-NOT: s4Test16UnavailableClassCMa
185-
186-
// MARK: E
187-
188-
// CHECK: s4Test1EOwug
189-
// CHECK: s4Test1EOMa
190-
191-
// MARK: unavailableFuncWithNestedType().Nested
192-
193-
// CHECK-NO-STRIP: s4Test29unavailableFuncWithNestedTypeyyF0E0L_VMa
194-
// CHECK-STRIP-NOT: s4Test29unavailableFuncWithNestedTypeyyF0E0L_VMa
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// RUN: %target-swift-frontend -parse-as-library -module-name Test -validate-tbd-against-ir=missing %s -emit-ir | %FileCheck %s --check-prefixes=CHECK,CHECK-NO-STRIP
2+
3+
// RUN: %target-swift-frontend -parse-as-library -module-name Test -validate-tbd-against-ir=missing -unavailable-decl-optimization=complete %s -emit-ir | %FileCheck %s --check-prefixes=CHECK,CHECK-STRIP
4+
5+
public class AvailableClass<T> {
6+
// CHECK-NO-STRIP: s4Test14AvailableClassC19unavailablePropertyxvg
7+
// CHECK-NO-STRIP: s4Test14AvailableClassC19unavailablePropertyxvs
8+
// CHECK-NO-STRIP: s4Test14AvailableClassC19unavailablePropertyxvM
9+
// CHECK-STRIP-NOT: s4Test14AvailableClassC19unavailablePropertyxvg
10+
// CHECK-STRIP-NOT: s4Test14AvailableClassC19unavailablePropertyxvs
11+
// CHECK-STRIP-NOT: s4Test14AvailableClassC19unavailablePropertyxvM
12+
@available(*, unavailable)
13+
public var unavailableProperty: T
14+
15+
// CHECK-NO-STRIP: s4Test14AvailableClassCyACyxGxcfC
16+
// CHECK-NO-STRIP: s4Test14AvailableClassCyACyxGxcfc
17+
// CHECK-STRIP-NOT: s4Test14AvailableClassCyACyxGxcfC
18+
// CHECK-STRIP-NOT: s4Test14AvailableClassCyACyxGxcfc
19+
@available(*, unavailable)
20+
public init(_ t: T) { fatalError() }
21+
22+
// CHECK: s4Test14AvailableClassCfd
23+
// CHECK: s4Test14AvailableClassCfD
24+
deinit {}
25+
}
26+
27+
@available(*, unavailable)
28+
public class UnavailableClass<T> {
29+
// CHECK-NO-STRIP: s4Test16UnavailableClassC8propertyxvg
30+
// CHECK-NO-STRIP: s4Test16UnavailableClassC8propertyxvs
31+
// CHECK-NO-STRIP: s4Test16UnavailableClassC8propertyxvM
32+
// CHECK-STRIP-NOT: s4Test16UnavailableClassC8propertyxvg
33+
// CHECK-STRIP-NOT: s4Test16UnavailableClassC8propertyxvs
34+
// CHECK-STRIP-NOT: s4Test16UnavailableClassC8propertyxvM
35+
public var property: T
36+
37+
// CHECK-NO-STRIP: s4Test16UnavailableClassCyACyxGxcfC
38+
// CHECK-NO-STRIP: s4Test16UnavailableClassCyACyxGxcfc
39+
// CHECK-STRIP-NOT: s4Test16UnavailableClassCyACyxGxcfC
40+
// CHECK-STRIP-NOT: s4Test16UnavailableClassCyACyxGxcfc
41+
public init(_ t: T) {
42+
self.property = t
43+
}
44+
45+
// CHECK-NO-STRIP: s4Test16UnavailableClassCfd
46+
// CHECK-NO-STRIP: s4Test16UnavailableClassCfD
47+
// CHECK-STRIP-NOT: s4Test16UnavailableClassCfd
48+
// CHECK-STRIP-NOT: s4Test16UnavailableClassCfD
49+
deinit {}
50+
}
51+
52+
// CHECK: s4Test14AvailableClassCMa
53+
54+
// CHECK-NO-STRIP: s4Test16UnavailableClassCMa
55+
// CHECK-STRIP-NOT: s4Test16UnavailableClassCMa
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// RUN: %target-swift-frontend -parse-as-library -module-name Test -validate-tbd-against-ir=missing %s -emit-ir | %FileCheck %s --check-prefixes=CHECK,CHECK-NO-STRIP
2+
3+
// RUN: %target-swift-frontend -parse-as-library -module-name Test -validate-tbd-against-ir=missing -unavailable-decl-optimization=complete %s -emit-ir | %FileCheck %s --check-prefixes=CHECK,CHECK-STRIP
4+
5+
// CHECK-NO-STRIP: s4Test1SVAA1PAAMc
6+
// CHECK-STRIP-NOT: s4Test1SVAA1PAAMc
7+
8+
// CHECK-NO-STRIP: s4Test1SVAA1PAAWP
9+
// CHECK-STRIP-NOT: s4Test1SVAA1PAAWP
10+
11+
// CHECK-NO-STRIP: s4Test1PMp
12+
// CHECK-STRIP-NOT: s4Test1PMp
13+
14+
@available(*, unavailable)
15+
public protocol P {
16+
func requirement()
17+
}
18+
19+
public struct S {}
20+
21+
@available(*, unavailable)
22+
extension S: P {
23+
// CHECK-NO-STRIP: s4Test1SV11requirementyyF
24+
// CHECK-STRIP-NOT: s4Test1SV11requirementyyF
25+
public func requirement() {}
26+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// RUN: %target-swift-frontend -parse-as-library -module-name Test -validate-tbd-against-ir=missing %s -emit-ir | %FileCheck %s --check-prefixes=CHECK,CHECK-NO-STRIP
2+
3+
// RUN: %target-swift-frontend -parse-as-library -module-name Test -validate-tbd-against-ir=missing -unavailable-decl-optimization=complete %s -emit-ir | %FileCheck %s --check-prefixes=CHECK,CHECK-STRIP
4+
5+
// CHECK: private constant [27 x i8] c"availableEnumAvailableCase\00"
6+
7+
// FIXME: Should this reflection metadata for an unavailable case be stripped?
8+
// CHECK: private constant [29 x i8] c"availableEnumUnavailableCase\00"
9+
10+
// CHECK-NO-STRIP: private constant [25 x i8] c"unavailableEnumFirstCase\00"
11+
// CHECK-STRIP-NOT: private constant [25 x i8] c"unavailableEnumFirstCase\00"
12+
13+
14+
public enum AvailableEnum {
15+
case availableEnumAvailableCase
16+
17+
@available(*, unavailable)
18+
case availableEnumUnavailableCase
19+
20+
// CHECK-NO-STRIP: s4Test13AvailableEnumO17unavailableMethodyyF
21+
// CHECK-STRIP-NOT: s4Test13AvailableEnumO17unavailableMethodyyF
22+
@available(*, unavailable)
23+
public func unavailableMethod() {}
24+
25+
// CHECK: s4Test13AvailableEnumO21__derived_enum_equalsySbAC_ACtFZ
26+
// CHECK: s4Test13AvailableEnumO4hash4intoys6HasherVz_tF
27+
// CHECK: s4Test13AvailableEnumO9hashValueSivg
28+
}
29+
30+
@available(*, unavailable)
31+
public enum UnavailableEnum {
32+
case unavailableEnumFirstCase
33+
34+
// CHECK-NO-STRIP: s4Test15UnavailableEnumO6methodyyF
35+
// CHECK-STRIP-NOT: s4Test15UnavailableEnumO6methodyyF
36+
public func method() {}
37+
38+
// CHECK-NO-STRIP: s4Test15UnavailableEnumO21__derived_enum_equalsySbAC_ACtFZ
39+
// CHECK-STRIP-NOT: s4Test15UnavailableEnumO21__derived_enum_equalsySbAC_ACtFZ
40+
41+
// CHECK-NO-STRIP: s4Test15UnavailableEnumO4hash4intoys6HasherVz_tF
42+
// CHECK-STRIP-NOT: s4Test15UnavailableEnumO4hash4intoys6HasherVz_tF
43+
44+
// CHECK-NO-STRIP: s4Test15UnavailableEnumO9hashValueSivg
45+
// CHECK-STRIP-NOT: s4Test15UnavailableEnumO9hashValueSivg
46+
}
47+
48+
// CHECK: s4Test13AvailableEnumOwug
49+
50+
// CHECK: s4Test13AvailableEnumOMa
51+
52+
// CHECK-NO-STRIP: s4Test15UnavailableEnumOwug
53+
// CHECK-STRIP-NOT: s4Test15UnavailableEnumOwug
54+
55+
// CHECK-NO-STRIP: s4Test15UnavailableEnumOMa
56+
// CHECK-STRIP-NOT: s4Test15UnavailableEnumOMa
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// RUN: %target-swift-frontend -parse-as-library -module-name Test -validate-tbd-against-ir=missing %s -emit-ir | %FileCheck %s --check-prefixes=CHECK,CHECK-NO-STRIP
2+
3+
// RUN: %target-swift-frontend -parse-as-library -module-name Test -validate-tbd-against-ir=missing -unavailable-decl-optimization=complete %s -emit-ir | %FileCheck %s --check-prefixes=CHECK,CHECK-STRIP
4+
5+
// CHECK-NO-STRIP: s4Test29unavailableFuncWithNestedTypeyyF
6+
// CHECK-STRIP-NOT: s4Test29unavailableFuncWithNestedTypeyyF
7+
@available(*, unavailable)
8+
public func unavailableFuncWithNestedType() {
9+
struct NestedInFunction {
10+
// s4Test29unavailableFuncWithNestedTypeyyF0E10InFunctionL_VADycfC
11+
init() {}
12+
}
13+
14+
_ = NestedInFunction()
15+
}
16+
17+
// CHECK-NO-STRIP: s4Test29unavailableFuncWithNestedTypeyyF0E10InFunctionL_VADycfC
18+
// CHECK-STRIP-NOT: s4Test29unavailableFuncWithNestedTypeyyF0E10InFunctionL_VADycfC
19+
20+
public struct S {}
21+
22+
extension S {
23+
@available(*, unavailable)
24+
public struct NestedInExtension {
25+
// CHECK-NO-STRIP: s4Test1SV17NestedInExtensionV6methodyyF
26+
// CHECK-STRIP-NOT: s4Test1SV17NestedInExtensionV6methodyyF
27+
public func method() {}
28+
}
29+
}
30+
31+
// CHECK-NO-STRIP: s4Test1SV17NestedInExtensionVMa
32+
// CHECK-STRIP-NOT: s4Test1SV17NestedInExtensionVMa
33+
34+
// CHECK-NO-STRIP: s4Test29unavailableFuncWithNestedTypeyyF0E10InFunctionL_VMa
35+
// CHECK-STRIP-NOT: s4Test29unavailableFuncWithNestedTypeyyF0E10InFunctionL_VMa

0 commit comments

Comments
 (0)