Skip to content

Commit 8685141

Browse files
authored
'open' classes within 'public' structs should be considered open. (#11925)
Without this, our hack to give all open class vtable members public linkage at the LLVM level wasn't kicking in, and subclasses from other modules were getting link errors. rdar://problem/32885384
1 parent 79a3f9c commit 8685141

File tree

3 files changed

+34
-5
lines changed

3 files changed

+34
-5
lines changed

lib/AST/Decl.cpp

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1953,17 +1953,30 @@ AccessLevel ValueDecl::getEffectiveAccess() const {
19531953
break;
19541954
}
19551955

1956+
auto restrictToEnclosing = [this](AccessLevel effectiveAccess,
1957+
AccessLevel enclosingAccess) -> AccessLevel{
1958+
if (effectiveAccess == AccessLevel::Open &&
1959+
enclosingAccess == AccessLevel::Public &&
1960+
isa<NominalTypeDecl>(this)) {
1961+
// Special case: an open class may be contained in a public
1962+
// class/struct/enum. Leave effectiveAccess as is.
1963+
return effectiveAccess;
1964+
}
1965+
return std::min(effectiveAccess, enclosingAccess);
1966+
};
1967+
19561968
if (auto enclosingNominal = dyn_cast<NominalTypeDecl>(getDeclContext())) {
1957-
effectiveAccess = std::min(effectiveAccess,
1958-
enclosingNominal->getEffectiveAccess());
1969+
effectiveAccess =
1970+
restrictToEnclosing(effectiveAccess,
1971+
enclosingNominal->getEffectiveAccess());
19591972

19601973
} else if (auto enclosingExt = dyn_cast<ExtensionDecl>(getDeclContext())) {
19611974
// Just check the base type. If it's a constrained extension, Sema should
19621975
// have already enforced access more strictly.
19631976
if (auto extendedTy = enclosingExt->getExtendedType()) {
19641977
if (auto nominal = extendedTy->getAnyNominal()) {
1965-
effectiveAccess = std::min(effectiveAccess,
1966-
nominal->getEffectiveAccess());
1978+
effectiveAccess =
1979+
restrictToEnclosing(effectiveAccess, nominal->getEffectiveAccess());
19671980
}
19681981
}
19691982

test/IRGen/Inputs/vtable_symbol_linkage_base.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,18 @@ open class Base {
1010
private var privateVar: Int = 29
1111
internal var internalVar: Int = 30
1212
}
13+
14+
15+
public struct Namespace {
16+
open class Nested {
17+
public init() {}
18+
var storedProp: Int?
19+
}
20+
}
21+
22+
extension Namespace {
23+
open class ExtNested {
24+
public init() {}
25+
var storedProp: Int?
26+
}
27+
}

test/IRGen/vtable_symbol_linkage.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,5 @@ import BaseModule
99
public class Derived : Base {
1010
}
1111

12-
12+
public class DerivedNested : Namespace.Nested {}
13+
public class DerivedExtNested : Namespace.ExtNested {}

0 commit comments

Comments
 (0)