Skip to content

Commit 8732287

Browse files
Merge pull request #23074 from aschwaighofer/private_import_internal_storage_private_accessor
Serialization: Also serialize the filename for internal storage decls with private accessors
2 parents d00dcaa + f049269 commit 8732287

File tree

5 files changed

+57
-13
lines changed

5 files changed

+57
-13
lines changed

include/swift/AST/Decl.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4549,6 +4549,9 @@ class AbstractStorageDecl : public ValueDecl {
45494549
/// other modules.
45504550
bool exportsPropertyDescriptor() const;
45514551

4552+
/// True if any of the accessors to the storage is private or fileprivate.
4553+
bool hasPrivateAccessor() const;
4554+
45524555
// Implement isa/cast/dyncast/etc.
45534556
static bool classof(const Decl *D) {
45544557
return D->getKind() >= DeclKind::First_AbstractStorageDecl &&

lib/AST/Decl.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4419,6 +4419,14 @@ void AbstractStorageDecl::overwriteImplInfo(StorageImplInfo implInfo) {
44194419
Accessors.getPointer()->overwriteImplInfo(implInfo);
44204420
}
44214421

4422+
bool AbstractStorageDecl::hasPrivateAccessor() const {
4423+
for (auto accessor : getAllAccessors()) {
4424+
if (hasPrivateOrFilePrivateFormalAccess(accessor))
4425+
return true;
4426+
}
4427+
return false;
4428+
}
4429+
44224430
void AbstractStorageDecl::setAccessors(StorageImplInfo implInfo,
44234431
SourceLoc lbraceLoc,
44244432
ArrayRef<AccessorDecl *> accessors,

lib/Serialization/Serialization.cpp

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2693,19 +2693,37 @@ void Serializer::writeDecl(const Decl *D) {
26932693
}
26942694

26952695
if (auto *value = dyn_cast<ValueDecl>(D)) {
2696-
if (value->getFormalAccess() <= swift::AccessLevel::FilePrivate &&
2697-
!value->getDeclContext()->isLocalContext()) {
2696+
auto *storage = dyn_cast<AbstractStorageDecl>(value);
2697+
auto access = value->getFormalAccess();
2698+
// Emit the private descriminator for private decls.
2699+
// FIXME: We shouldn't need to encode this for /all/ private decls.
2700+
// In theory we can follow the same rules as mangling and only include
2701+
// the outermost private context.
2702+
bool shouldEmitPrivateDescriminator =
2703+
access <= swift::AccessLevel::FilePrivate &&
2704+
!value->getDeclContext()->isLocalContext();
2705+
2706+
// Emit the the filename for private mapping for private decls and
2707+
// decls with private accessors if compiled with -enable-private-imports.
2708+
bool shouldEmitFilenameForPrivate =
2709+
M->arePrivateImportsEnabled() &&
2710+
!value->getDeclContext()->isLocalContext() &&
2711+
(access <= swift::AccessLevel::FilePrivate ||
2712+
(storage &&
2713+
storage->getFormalAccess() >= swift::AccessLevel::Internal &&
2714+
storage->hasPrivateAccessor()));
2715+
2716+
if (shouldEmitFilenameForPrivate || shouldEmitPrivateDescriminator) {
26982717
auto topLevelContext = value->getDeclContext()->getModuleScopeContext();
26992718
if (auto *enclosingFile = dyn_cast<FileUnit>(topLevelContext)) {
2700-
// FIXME: We shouldn't need to encode this for /all/ private decls.
2701-
// In theory we can follow the same rules as mangling and only include
2702-
// the outermost private context.
2703-
Identifier discriminator =
2704-
enclosingFile->getDiscriminatorForPrivateValue(value);
2705-
unsigned abbrCode =
2706-
DeclTypeAbbrCodes[PrivateDiscriminatorLayout::Code];
2707-
PrivateDiscriminatorLayout::emitRecord(Out, ScratchRecord, abbrCode,
2708-
addDeclBaseNameRef(discriminator));
2719+
if (shouldEmitPrivateDescriminator) {
2720+
Identifier discriminator =
2721+
enclosingFile->getDiscriminatorForPrivateValue(value);
2722+
unsigned abbrCode =
2723+
DeclTypeAbbrCodes[PrivateDiscriminatorLayout::Code];
2724+
PrivateDiscriminatorLayout::emitRecord(
2725+
Out, ScratchRecord, abbrCode, addDeclBaseNameRef(discriminator));
2726+
}
27092727
auto getFilename = [](FileUnit *enclosingFile,
27102728
const ValueDecl *decl) -> StringRef {
27112729
if (auto *SF = dyn_cast<SourceFile>(enclosingFile)) {
@@ -2715,8 +2733,7 @@ void Serializer::writeDecl(const Decl *D) {
27152733
}
27162734
return StringRef();
27172735
};
2718-
// Only if compiled with -enable-private-imports.
2719-
if (M->arePrivateImportsEnabled()) {
2736+
if (shouldEmitFilenameForPrivate) {
27202737
auto filename = getFilename(enclosingFile, value);
27212738
if (!filename.empty()) {
27222739
auto filenameID = addFilename(filename);

test/Serialization/Inputs/private_import_other.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,10 @@ struct Value {
88
extension Value {
99
fileprivate func foo() {}
1010
}
11+
12+
struct Internal {
13+
private(set) var internalVarWithPrivateSetter : Int = 0
14+
fileprivate(set) var internalVarWithFilePrivateSetter : Int = 0
15+
public private(set) var publicVarWithPrivateSetter : Int = 0
16+
public fileprivate(set) var publicVarWithFilePrivateSetter : Int = 0
17+
}

test/Serialization/private_import.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,15 @@
4141
@_private(sourceFile: "private_import_other.swift") import private_import
4242
@_private(sourceFile: "private_import.swift") import client
4343

44+
extension Internal {
45+
mutating func set() {
46+
self.internalVarWithPrivateSetter = 1
47+
self.internalVarWithFilePrivateSetter = 1
48+
self.publicVarWithPrivateSetter = 1
49+
self.publicVarWithFilePrivateSetter = 1
50+
}
51+
}
52+
4453
Base().foo()
4554
// This should not be ambigious.
4655
Base().bar()

0 commit comments

Comments
 (0)