Skip to content

Commit 72bf1e9

Browse files
authored
Merge pull request #24661 from rintaro/5.1-serialization-swiftonly-system-module
[5.1][Serialization] Support Swift only system module
2 parents a2bb46e + ba6723b commit 72bf1e9

16 files changed

+297
-32
lines changed

include/swift/AST/Decl.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -597,7 +597,7 @@ class alignas(1 << DeclAlignInBits) Decl {
597597
HasAnyUnavailableValues : 1
598598
);
599599

600-
SWIFT_INLINE_BITFIELD(ModuleDecl, TypeDecl, 1+1+1+1+1+1,
600+
SWIFT_INLINE_BITFIELD(ModuleDecl, TypeDecl, 1+1+1+1+1+1+1,
601601
/// If the module was or is being compiled with `-enable-testing`.
602602
TestingEnabled : 1,
603603

@@ -616,7 +616,10 @@ class alignas(1 << DeclAlignInBits) Decl {
616616
PrivateImportsEnabled : 1,
617617

618618
// If the module is compiled with `-enable-implicit-dynamic`.
619-
ImplicitDynamicEnabled : 1
619+
ImplicitDynamicEnabled : 1,
620+
621+
// Whether the module is a system module.
622+
IsSystemModule : 1
620623
);
621624

622625
SWIFT_INLINE_BITFIELD(PrecedenceGroupDecl, Decl, 1+2,

include/swift/AST/Module.h

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,15 @@ class ModuleDecl : public DeclContext, public TypeDecl {
325325
Bits.ModuleDecl.RawResilienceStrategy = unsigned(strategy);
326326
}
327327

328+
/// \returns true if this module is a system module; note that the StdLib is
329+
/// considered a system module.
330+
bool isSystemModule() const {
331+
return Bits.ModuleDecl.IsSystemModule;
332+
}
333+
void setIsSystemModule(bool flag = true) {
334+
Bits.ModuleDecl.IsSystemModule = flag;
335+
}
336+
328337
bool isResilient() const {
329338
return getResilienceStrategy() != ResilienceStrategy::Default;
330339
}
@@ -553,10 +562,6 @@ class ModuleDecl : public DeclContext, public TypeDecl {
553562
/// \returns true if this module is the "SwiftOnoneSupport" module;
554563
bool isOnoneSupportModule() const;
555564

556-
/// \returns true if this module is a system module; note that the StdLib is
557-
/// considered a system module.
558-
bool isSystemModule() const;
559-
560565
/// \returns true if traversal was aborted, false otherwise.
561566
bool walk(ASTWalker &Walker);
562567

include/swift/Serialization/SerializedModuleLoader.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ class SerializedModuleLoaderBase : public ModuleLoader {
5151
bool findModule(AccessPathElem moduleID,
5252
std::unique_ptr<llvm::MemoryBuffer> *moduleBuffer,
5353
std::unique_ptr<llvm::MemoryBuffer> *moduleDocBuffer,
54-
bool &isFramework);
54+
bool &isFramework, bool &isSystemModule);
5555

5656
/// Attempts to search the provided directory for a loadable serialized
5757
/// .swiftmodule with the provided `ModuleFilename`. Subclasses must

lib/AST/Module.cpp

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1283,16 +1283,6 @@ bool ModuleDecl::registerEntryPointFile(FileUnit *file, SourceLoc diagLoc,
12831283
return true;
12841284
}
12851285

1286-
bool ModuleDecl::isSystemModule() const {
1287-
if (isStdlibModule())
1288-
return true;
1289-
for (auto F : getFiles()) {
1290-
if (auto LF = dyn_cast<LoadedFile>(F))
1291-
return LF->isSystemModule();
1292-
}
1293-
return false;
1294-
}
1295-
12961286
template<bool respectVisibility>
12971287
static bool
12981288
forAllImportedModules(ModuleDecl *topLevel, ModuleDecl::AccessPathTy thisPath,

lib/ClangImporter/ClangImporter.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1670,6 +1670,7 @@ ModuleDecl *ClangImporter::Implementation::finishLoadingClangModule(
16701670
// but that's not correct for submodules.
16711671
Identifier name = SwiftContext.getIdentifier((*clangModule).Name);
16721672
result = ModuleDecl::create(name, SwiftContext);
1673+
result->setIsSystemModule(clangModule->IsSystem);
16731674
// Silence error messages about testably importing a Clang module.
16741675
result->setTestingEnabled();
16751676
result->setHasResolvedImports();
@@ -1836,6 +1837,7 @@ ClangModuleUnit *ClangImporter::Implementation::getWrapperForModule(
18361837
// FIXME: Handle hierarchical names better.
18371838
Identifier name = SwiftContext.getIdentifier(underlying->Name);
18381839
auto wrapper = ModuleDecl::create(name, SwiftContext);
1840+
wrapper->setIsSystemModule(underlying->IsSystem);
18391841
// Silence error messages about testably importing a Clang module.
18401842
wrapper->setTestingEnabled();
18411843
wrapper->setHasResolvedImports();

lib/Serialization/SerializedModuleLoader.cpp

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,16 @@ enum class SearchPathKind {
6363
/// non-None value. Returns the return value from \p body, or \c None.
6464
Optional<bool> forEachModuleSearchPath(
6565
const ASTContext &Ctx,
66-
llvm::function_ref<Optional<bool>(StringRef, SearchPathKind)> callback) {
66+
llvm::function_ref<Optional<bool>(StringRef, SearchPathKind, bool isSystem)>
67+
callback) {
6768
for (const auto &path : Ctx.SearchPathOpts.ImportSearchPaths)
68-
if (auto result = callback(path, SearchPathKind::Import))
69+
if (auto result =
70+
callback(path, SearchPathKind::Import, /*isSystem=*/false))
6971
return result;
7072

7173
for (const auto &path : Ctx.SearchPathOpts.FrameworkSearchPaths)
72-
if (auto result = callback(path.Path, SearchPathKind::Framework))
74+
if (auto result =
75+
callback(path.Path, SearchPathKind::Framework, path.IsSystem))
7376
return result;
7477

7578
// Apple platforms have extra implicit framework search paths:
@@ -78,17 +81,20 @@ Optional<bool> forEachModuleSearchPath(
7881
SmallString<128> scratch;
7982
scratch = Ctx.SearchPathOpts.SDKPath;
8083
llvm::sys::path::append(scratch, "System", "Library", "Frameworks");
81-
if (auto result = callback(scratch, SearchPathKind::Framework))
84+
if (auto result =
85+
callback(scratch, SearchPathKind::Framework, /*isSystem=*/true))
8286
return result;
8387

8488
scratch = Ctx.SearchPathOpts.SDKPath;
8589
llvm::sys::path::append(scratch, "Library", "Frameworks");
86-
if (auto result = callback(scratch, SearchPathKind::Framework))
90+
if (auto result =
91+
callback(scratch, SearchPathKind::Framework, /*isSystem=*/true))
8792
return result;
8893
}
8994

9095
for (auto importPath : Ctx.SearchPathOpts.RuntimeLibraryImportPaths) {
91-
if (auto result = callback(importPath, SearchPathKind::RuntimeLibrary))
96+
if (auto result = callback(importPath, SearchPathKind::RuntimeLibrary,
97+
/*isSystem=*/true))
9298
return result;
9399
}
94100

@@ -150,7 +156,8 @@ void SerializedModuleLoaderBase::collectVisibleTopLevelModuleNamesImpl(
150156
return false;
151157
};
152158

153-
forEachModuleSearchPath(Ctx, [&](StringRef searchPath, SearchPathKind Kind) {
159+
forEachModuleSearchPath(Ctx, [&](StringRef searchPath, SearchPathKind Kind,
160+
bool isSystem) {
154161
switch (Kind) {
155162
case SearchPathKind::Import: {
156163
// Look for:
@@ -369,7 +376,7 @@ bool
369376
SerializedModuleLoaderBase::findModule(AccessPathElem moduleID,
370377
std::unique_ptr<llvm::MemoryBuffer> *moduleBuffer,
371378
std::unique_ptr<llvm::MemoryBuffer> *moduleDocBuffer,
372-
bool &isFramework) {
379+
bool &isFramework, bool &isSystemModule) {
373380
llvm::SmallString<64> moduleName(moduleID.first.str());
374381
ModuleFilenamePair fileNames(moduleName);
375382

@@ -413,8 +420,11 @@ SerializedModuleLoaderBase::findModule(AccessPathElem moduleID,
413420
};
414421

415422
auto result = forEachModuleSearchPath(
416-
Ctx, [&](StringRef path, SearchPathKind Kind) -> Optional<bool> {
423+
Ctx,
424+
[&](StringRef path, SearchPathKind Kind,
425+
bool isSystem) -> Optional<bool> {
417426
currPath = path;
427+
isSystemModule = isSystem;
418428

419429
switch (Kind) {
420430
case SearchPathKind::Import:
@@ -547,6 +557,15 @@ FileUnit *SerializedModuleLoaderBase::loadAST(
547557
loadInfo.status =
548558
loadedModuleFile->associateWithFileContext(fileUnit, diagLocOrInvalid,
549559
treatAsPartialModule);
560+
561+
// FIXME: This seems wrong. Overlay for system Clang module doesn't
562+
// necessarily mean it's "system" module. User can make their own overlay
563+
// in non-system directory.
564+
// Remove this block after we fix the test suite.
565+
if (auto shadowed = loadedModuleFile->getShadowedModule())
566+
if (shadowed->isSystemModule())
567+
M.setIsSystemModule(true);
568+
550569
if (loadInfo.status == serialization::Status::Valid) {
551570
Ctx.bumpGeneration();
552571
LoadedModuleFiles.emplace_back(std::move(loadedModuleFile),
@@ -748,7 +767,8 @@ bool SerializedModuleLoaderBase::canImportModule(
748767
std::pair<Identifier, SourceLoc> mID) {
749768
// Look on disk.
750769
bool isFramework = false;
751-
return findModule(mID, nullptr, nullptr, isFramework);
770+
bool isSystemModule = false;
771+
return findModule(mID, nullptr, nullptr, isFramework, isSystemModule);
752772
}
753773

754774
bool MemoryBufferSerializedModuleLoader::canImportModule(
@@ -766,13 +786,14 @@ SerializedModuleLoaderBase::loadModule(SourceLoc importLoc,
766786

767787
auto moduleID = path[0];
768788
bool isFramework = false;
789+
bool isSystemModule = false;
769790

770791
std::unique_ptr<llvm::MemoryBuffer> moduleInputBuffer;
771792
std::unique_ptr<llvm::MemoryBuffer> moduleDocInputBuffer;
772793

773794
// Look on disk.
774795
if (!findModule(moduleID, &moduleInputBuffer, &moduleDocInputBuffer,
775-
isFramework)) {
796+
isFramework, isSystemModule)) {
776797
return nullptr;
777798
}
778799
if (dependencyTracker) {
@@ -786,6 +807,7 @@ SerializedModuleLoaderBase::loadModule(SourceLoc importLoc,
786807
assert(moduleInputBuffer);
787808

788809
auto M = ModuleDecl::create(moduleID.first, Ctx);
810+
M->setIsSystemModule(isSystemModule);
789811
Ctx.LoadedModules[moduleID.first] = M;
790812
SWIFT_DEFER { M->setHasResolvedImports(); };
791813

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %{python} %utils/split_file.py -o %t %s
3+
4+
// RUN: mkdir -p %t/SDK/Frameworks/SomeModule.framework/Modules/SomeModule.swiftmodule
5+
// RUN: %target-swift-frontend \
6+
// RUN: -emit-module \
7+
// RUN: -module-name SomeModule \
8+
// RUN: -o %t/SDK/Frameworks/SomeModule.framework/Modules/SomeModule.swiftmodule/%module-target-triple.swiftmodule \
9+
// RUN: -swift-version 5 \
10+
// RUN: %t/SomeModule.swift
11+
12+
// RUN: %target-swift-ide-test -code-completion -sdk %t/SDK -iframework %t/SDK/Frameworks -source-filename %t/main.swift -code-completion-token=GLOBAL | %FileCheck --check-prefix GLOBAL %s
13+
// RUN: %target-swift-ide-test -code-completion -sdk %t/SDK -iframework %t/SDK/Frameworks -source-filename %t/main.swift -code-completion-token=INSTANCE | %FileCheck --check-prefix INSTANCE %s
14+
// RUN: %target-swift-ide-test -code-completion -sdk %t/SDK -iframework %t/SDK/Frameworks -source-filename %t/main.swift -code-completion-token=INITIALIZER | %FileCheck --check-prefix INITIALIZER %s
15+
16+
// Test that declarations starting with '_' from system module doesn't apper in
17+
// code completion.
18+
19+
// BEGIN SomeModule.swift
20+
21+
public struct SomeValue {
22+
internal var internalValue: Int { return 1 }
23+
public var _secretValue: Int { return 1 }
24+
public var publicValue: Int { return 1 }
25+
26+
internal func internalMethod() -> Int { return 1 }
27+
public func _secretMethod() -> Int { return 1 }
28+
public func publicMethod() -> Int { return 1 }
29+
30+
internal init(internal: Int) {}
31+
public init(_secret: Int) {}
32+
public init(public: Int) {}
33+
}
34+
35+
internal func internalFunc() {}
36+
public func _secretFunc() {}
37+
public func publicFunc() {}
38+
39+
// BEGIN main.swift
40+
import SomeModule
41+
42+
func test(value: SomeValue) {
43+
let _ = #^GLOBAL^#
44+
// GLOBAL: Begin completions
45+
// GLOBAL-NOT: _secretFunc
46+
// GLOBAL-NOT: internalFunc
47+
// GLOBAL-DAG: Decl[Struct]/OtherModule[SomeModule]: SomeValue[#SomeValue#];
48+
// GLOBAL-DAG: Decl[FreeFunction]/OtherModule[SomeModule]: publicFunc()[#Void#];
49+
// GLOBAL: End completions
50+
51+
let _ = value.#^INSTANCE^#
52+
// INSTANCE: Begin completions, 3 items
53+
// INSTANCE-DAG: Keyword[self]/CurrNominal: self[#SomeValue#];
54+
// INSTANCE-DAG: Decl[InstanceVar]/CurrNominal: publicValue[#Int#];
55+
// INSTANCE-DAG: Decl[InstanceMethod]/CurrNominal: publicMethod()[#Int#];
56+
// INSTANCE: End completions
57+
58+
let _ = SomeValue(#^INITIALIZER^#
59+
// INITIALIZER: Begin completions, 1 items
60+
// INITIALIZER-DAG: Decl[Constructor]/CurrNominal: ['(']{#public: Int#}[')'][#SomeValue#];
61+
// INITIALIZER: End completions
62+
}

0 commit comments

Comments
 (0)