Skip to content

Commit c61cc6f

Browse files
committed
[AST] Add SPI information to public access scopes
1 parent fb1c71c commit c61cc6f

File tree

3 files changed

+21
-9
lines changed

3 files changed

+21
-9
lines changed

include/swift/AST/AccessScope.h

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,16 @@ namespace swift {
2424
/// a particular declaration can be accessed.
2525
class AccessScope {
2626
/// The declaration context (if not public) along with a bit saying
27-
/// whether this scope is private (or not).
27+
/// whether this scope is private, SPI or not.
28+
/// If the declaration context is set, the bit means that the scope is
29+
/// private or not. If the declaration context is null, the bit means that
30+
/// this scope is SPI or not.
2831
llvm::PointerIntPair<const DeclContext *, 1, bool> Value;
32+
2933
public:
30-
AccessScope(const DeclContext *DC, bool isPrivate = false);
34+
AccessScope(const DeclContext *DC, bool isPrivate = false, bool isSPI = false);
3135

32-
static AccessScope getPublic() { return AccessScope(nullptr); }
36+
static AccessScope getPublic(bool isSPI = false) { return AccessScope(nullptr, false, isSPI); }
3337

3438
/// Check if private access is allowed. This is a lexical scope check in Swift
3539
/// 3 mode. In Swift 4 mode, declarations and extensions of the same type will
@@ -46,18 +50,24 @@ class AccessScope {
4650
}
4751

4852
bool isPublic() const { return !Value.getPointer(); }
49-
bool isPrivate() const { return Value.getInt(); }
53+
bool isPrivate() const { return Value.getPointer() && Value.getInt(); }
5054
bool isFileScope() const;
5155
bool isInternal() const;
5256

57+
// Is this a public scope
58+
bool isSPI() const { return !Value.getPointer() && Value.getInt(); }
59+
5360
/// Returns true if this is a child scope of the specified other access scope.
5461
///
5562
/// \see DeclContext::isChildContextOf
5663
bool isChildOf(AccessScope AS) const {
5764
if (!isPublic() && !AS.isPublic())
5865
return allowsPrivateAccess(getDeclContext(), AS.getDeclContext());
59-
if (isPublic() && AS.isPublic())
66+
if (isPublic() && AS.isPublic()) {
67+
if (isSPI() != AS.isSPI())
68+
return isSPI();
6069
return false;
70+
}
6171
return AS.isPublic();
6272
}
6373

@@ -76,6 +86,8 @@ class AccessScope {
7686
/// have common intersection, or None if scopes don't intersect.
7787
const Optional<AccessScope> intersectWith(AccessScope accessScope) const {
7888
if (hasEqualDeclContextWith(accessScope)) {
89+
if (isSPI())
90+
return *this;
7991
if (isPrivate())
8092
return *this;
8193
return accessScope;

lib/AST/DeclContext.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -954,14 +954,16 @@ getPrivateDeclContext(const DeclContext *DC, const SourceFile *useSF) {
954954
return lastExtension ? lastExtension : DC;
955955
}
956956

957-
AccessScope::AccessScope(const DeclContext *DC, bool isPrivate)
958-
: Value(DC, isPrivate) {
957+
AccessScope::AccessScope(const DeclContext *DC, bool isPrivate, bool isSPI)
958+
: Value(DC, isPrivate || isSPI) {
959959
if (isPrivate) {
960960
DC = getPrivateDeclContext(DC, DC->getParentSourceFile());
961961
Value.setPointer(DC);
962962
}
963963
if (!DC || isa<ModuleDecl>(DC))
964964
assert(!isPrivate && "public or internal scope can't be private");
965+
if (DC)
966+
assert(!isSPI && "only public scopes can be SPI");
965967
}
966968

967969
bool AccessScope::isFileScope() const {

lib/Sema/TypeCheckAccess.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,8 +171,6 @@ class TypeAccessScopeDiagnoser : private ASTWalker {
171171
AccessScope accessScope,
172172
const DeclContext *useDC,
173173
bool treatUsableFromInlineAsPublic) {
174-
assert(!accessScope.isPublic() &&
175-
"why would we need to find a public access scope?");
176174
if (TR == nullptr)
177175
return nullptr;
178176
TypeAccessScopeDiagnoser diagnoser(accessScope, useDC,

0 commit comments

Comments
 (0)