Skip to content

[Explicit Module Builds] Prevent SerializedModuleLoader from running in Explicit Module Build mode. #32903

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions include/swift/Frontend/Frontend.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@

namespace swift {

class SerializedModuleLoader;
class SerializedModuleLoaderBase;
class MemoryBufferSerializedModuleLoader;
class SILModule;

Expand Down Expand Up @@ -434,7 +434,7 @@ class CompilerInstance {
std::unique_ptr<UnifiedStatsReporter> Stats;

mutable ModuleDecl *MainModule = nullptr;
SerializedModuleLoader *SML = nullptr;
SerializedModuleLoaderBase *DefaultSerializedLoader = nullptr;
MemoryBufferSerializedModuleLoader *MemoryBufferLoader = nullptr;

/// Contains buffer IDs for input source code files.
Expand Down
17 changes: 9 additions & 8 deletions include/swift/Serialization/SerializedModuleLoader.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,9 @@ struct SerializedModuleBaseName {
std::string getName(file_types::ID fileTy) const;
};

/// Common functionality shared between \c SerializedModuleLoader,
/// \c ModuleInterfaceLoader and \c MemoryBufferSerializedModuleLoader.
/// Common functionality shared between \c ImplicitSerializedModuleLoader,
/// \c ModuleInterfaceLoader, \c ExplicitSwiftModuleLoader
/// and \c MemoryBufferSerializedModuleLoader.
class SerializedModuleLoaderBase : public ModuleLoader {
/// A { module, generation # } pair.
using LoadedModulePair = std::pair<std::unique_ptr<ModuleFile>, unsigned>;
Expand Down Expand Up @@ -215,9 +216,9 @@ class SerializedModuleLoaderBase : public ModuleLoader {
};

/// Imports serialized Swift modules into an ASTContext.
class SerializedModuleLoader : public SerializedModuleLoaderBase {
class ImplicitSerializedModuleLoader : public SerializedModuleLoaderBase {

SerializedModuleLoader(ASTContext &ctx, DependencyTracker *tracker,
ImplicitSerializedModuleLoader(ASTContext &ctx, DependencyTracker *tracker,
ModuleLoadingMode loadMode, bool IgnoreSwiftSourceInfo)
: SerializedModuleLoaderBase(ctx, tracker, loadMode, IgnoreSwiftSourceInfo)
{}
Expand All @@ -236,7 +237,7 @@ class SerializedModuleLoader : public SerializedModuleLoaderBase {
const SerializedModuleBaseName &BaseName) override;

public:
virtual ~SerializedModuleLoader();
virtual ~ImplicitSerializedModuleLoader();

/// Append visible module names to \p names. Note that names are possibly
/// duplicated, and not guaranteed to be ordered in any way.
Expand All @@ -245,12 +246,12 @@ class SerializedModuleLoader : public SerializedModuleLoaderBase {

/// Create a new importer that can load serialized Swift modules
/// into the given ASTContext.
static std::unique_ptr<SerializedModuleLoader>
static std::unique_ptr<ImplicitSerializedModuleLoader>
create(ASTContext &ctx, DependencyTracker *tracker = nullptr,
ModuleLoadingMode loadMode = ModuleLoadingMode::PreferSerialized,
bool IgnoreSwiftSourceInfo = false) {
return std::unique_ptr<SerializedModuleLoader>{
new SerializedModuleLoader(ctx, tracker, loadMode, IgnoreSwiftSourceInfo)
return std::unique_ptr<ImplicitSerializedModuleLoader>{
new ImplicitSerializedModuleLoader(ctx, tracker, loadMode, IgnoreSwiftSourceInfo)
};
}
};
Expand Down
2 changes: 1 addition & 1 deletion include/swift/Serialization/Validation.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ ValidationInfo validateSerializedAST(
/// Status::Valid.
/// - \p moduleBufferID and \p moduleDocBufferID are the buffer identifiers
/// of the module input and doc input buffers respectively (\ref
/// SerializedModuleLoader::loadAST, \ref ModuleFile::load).
/// SerializedModuleLoaderBase::loadAST, \ref ModuleFile::load).
/// - \p loadedModuleFile is an invalid loaded module.
/// - \p ModuleName is the name used to refer to the module in diagnostics.
void diagnoseSerializedASTLoadFailure(
Expand Down
35 changes: 22 additions & 13 deletions lib/Frontend/Frontend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -424,14 +424,17 @@ void CompilerInstance::setUpDiagnosticOptions() {
// Ideally, we'd get rid of it.
// 2. MemoryBufferSerializedModuleLoader: This is used by LLDB, because it might
// already have the module available in memory.
// 3. ModuleInterfaceLoader: Tries to find an up-to-date swiftmodule. If it
// 3. ExplicitSwiftModuleLoader: Loads a serialized module if it can, provided
// this modules was specified as an explicit input to the compiler.
// 4. ModuleInterfaceLoader: Tries to find an up-to-date swiftmodule. If it
// succeeds, it issues a particular "error" (see
// [Note: ModuleInterfaceLoader-defer-to-SerializedModuleLoader]), which
// [Note: ModuleInterfaceLoader-defer-to-ImplicitSerializedModuleLoader]), which
// is interpreted by the overarching loader as a command to use the
// SerializedModuleLoader. If we failed to find a .swiftmodule, this falls
// ImplicitSerializedModuleLoader. If we failed to find a .swiftmodule, this falls
Comment on lines -429 to +433
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please be careful about updating comments. There are a couple of issues here:

  1. This is exceeding the line length limit now.
  2. This broke a reference to the note, since the reference now has a new name but the note's name in ModuleInterfaceLoader.cpp is not changed in this PR.

I'm going to fix these two issues in an upcoming PR, it's not a big deal; just something to be careful about.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR with fix: #33124

// back to using an interface. Actual errors lead to diagnostics.
// 4. SerializedModuleLoader: Loads a serialized module if it can.
// 5. ClangImporter: This must come after all the Swift module loaders because
// 5. ImplicitSerializedModuleLoader: Loads a serialized module if it can.
// Used for implicit loading of modules from the compiler's search paths.
// 6. ClangImporter: This must come after all the Swift module loaders because
// in the presence of overlays and mixed-source frameworks, we want to prefer
// the overlay or framework module over the underlying Clang module.
bool CompilerInstance::setUpModuleLoaders() {
Expand Down Expand Up @@ -484,15 +487,18 @@ bool CompilerInstance::setUpModuleLoaders() {

// If implicit modules are disabled, we need to install an explicit module
// loader.
if (Invocation.getFrontendOptions().DisableImplicitModules) {
bool ExplicitModuleBuild = Invocation.getFrontendOptions().DisableImplicitModules;
if (ExplicitModuleBuild) {
auto ESML = ExplicitSwiftModuleLoader::create(
*Context,
getDependencyTracker(), MLM,
Invocation.getSearchPathOptions().ExplicitSwiftModules,
Invocation.getSearchPathOptions().ExplicitSwiftModuleMap,
IgnoreSourceInfoFile);
this->DefaultSerializedLoader = ESML.get();
Context->addModuleLoader(std::move(ESML));
}

if (MLM != ModuleLoadingMode::OnlySerialized) {
auto const &Clang = clangImporter->getClangInstance();
std::string ModuleCachePath = getModuleCachePathFromClang(Clang);
Expand All @@ -507,12 +513,14 @@ bool CompilerInstance::setUpModuleLoaders() {
Context->addModuleLoader(std::move(PIML), false, false, true);
}

std::unique_ptr<SerializedModuleLoader> SML =
SerializedModuleLoader::create(*Context, getDependencyTracker(), MLM,
if (!ExplicitModuleBuild) {
std::unique_ptr<ImplicitSerializedModuleLoader> ISML =
ImplicitSerializedModuleLoader::create(*Context, getDependencyTracker(), MLM,
IgnoreSourceInfoFile);
this->SML = SML.get();
Context->addModuleLoader(std::move(SML));

this->DefaultSerializedLoader = ISML.get();
Context->addModuleLoader(std::move(ISML));
}

Context->addModuleLoader(std::move(clangImporter), /*isClang*/ true);

return false;
Expand Down Expand Up @@ -868,6 +876,7 @@ bool CompilerInstance::loadStdlibIfNeeded() {

bool CompilerInstance::loadPartialModulesAndImplicitImports(
ModuleDecl *mod, SmallVectorImpl<FileUnit *> &partialModules) const {
assert(DefaultSerializedLoader && "Expected module loader in Compiler Instance");
FrontendStatsTracer tracer(getStatsReporter(),
"load-partial-modules-and-implicit-imports");
// Force loading implicit imports. This is currently needed to allow
Expand All @@ -881,7 +890,7 @@ bool CompilerInstance::loadPartialModulesAndImplicitImports(
for (auto &PM : PartialModules) {
assert(PM.ModuleBuffer);
auto *file =
SML->loadAST(*mod, /*diagLoc*/ SourceLoc(), /*moduleInterfacePath*/ "",
DefaultSerializedLoader->loadAST(*mod, /*diagLoc*/ SourceLoc(), /*moduleInterfacePath*/ "",
std::move(PM.ModuleBuffer), std::move(PM.ModuleDocBuffer),
std::move(PM.ModuleSourceInfoBuffer),
/*isFramework*/ false);
Expand Down Expand Up @@ -974,7 +983,7 @@ void CompilerInstance::freeASTContext() {
TheSILTypes.reset();
Context.reset();
MainModule = nullptr;
SML = nullptr;
DefaultSerializedLoader = nullptr;
MemoryBufferLoader = nullptr;
PrimaryBufferIDs.clear();
}
Expand Down
8 changes: 4 additions & 4 deletions lib/Serialization/SerializedModuleLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ SerializedModuleLoaderBase::SerializedModuleLoaderBase(
IgnoreSwiftSourceInfoFile(IgnoreSwiftSourceInfoFile) {}

SerializedModuleLoaderBase::~SerializedModuleLoaderBase() = default;
SerializedModuleLoader::~SerializedModuleLoader() = default;
ImplicitSerializedModuleLoader::~ImplicitSerializedModuleLoader() = default;
MemoryBufferSerializedModuleLoader::~MemoryBufferSerializedModuleLoader() =
default;

Expand Down Expand Up @@ -243,7 +243,7 @@ void SerializedModuleLoaderBase::collectVisibleTopLevelModuleNamesImpl(
});
}

void SerializedModuleLoader::collectVisibleTopLevelModuleNames(
void ImplicitSerializedModuleLoader::collectVisibleTopLevelModuleNames(
SmallVectorImpl<Identifier> &names) const {
collectVisibleTopLevelModuleNamesImpl(
names, file_types::getExtension(file_types::TY_SwiftModuleFile));
Expand Down Expand Up @@ -397,7 +397,7 @@ llvm::ErrorOr<ModuleDependencies> SerializedModuleLoaderBase::scanModuleFile(
return std::move(dependencies);
}

std::error_code SerializedModuleLoader::findModuleFilesInDirectory(
std::error_code ImplicitSerializedModuleLoader::findModuleFilesInDirectory(
AccessPathElem ModuleID,
const SerializedModuleBaseName &BaseName,
SmallVectorImpl<char> *ModuleInterfacePath,
Expand Down Expand Up @@ -434,7 +434,7 @@ std::error_code SerializedModuleLoader::findModuleFilesInDirectory(
return std::error_code();
}

bool SerializedModuleLoader::maybeDiagnoseTargetMismatch(
bool ImplicitSerializedModuleLoader::maybeDiagnoseTargetMismatch(
SourceLoc sourceLocation, StringRef moduleName,
const SerializedModuleBaseName &absoluteBaseName) {
llvm::vfs::FileSystem &fs = *Ctx.SourceMgr.getFileSystem();
Expand Down
8 changes: 8 additions & 0 deletions test/ScanDependencies/can_import_with_map.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@
// RUN: echo "\"modulePath\": \"%/t/inputs/Foo.swiftmodule\"," >> %/t/inputs/map.json
// RUN: echo "\"docPath\": \"%/t/inputs/Foo.swiftdoc\"," >> %/t/inputs/map.json
// RUN: echo "\"sourceInfoPath\": \"%/t/inputs/Foo.swiftsourceinfo\"" >> %/t/inputs/map.json
// RUN: echo "}," >> %/t/inputs/map.json
// RUN: echo "{" >> %/t/inputs/map.json
// RUN: echo "\"moduleName\": \"Swift\"," >> %/t/inputs/map.json
// RUN: echo "\"modulePath\": \"%stdlib_module\"," >> %/t/inputs/map.json
// RUN: echo "}," >> %/t/inputs/map.json
// RUN: echo "{" >> %/t/inputs/map.json
// RUN: echo "\"moduleName\": \"SwiftOnoneSupport\"," >> %/t/inputs/map.json
// RUN: echo "\"modulePath\": \"%ononesupport_module\"," >> %/t/inputs/map.json
// RUN: echo "}]" >> %/t/inputs/map.json

// RUN: %target-swift-frontend -typecheck %s -explicit-swift-module-map-file %t/inputs/map.json -disable-implicit-swift-modules
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@
// RUN: echo "\"modulePath\": \"%/t/inputs/Foo-from-interface.swiftmodule\"," >> %/t/inputs/map.json
// RUN: echo "\"docPath\": \"%/t/inputs/Foo.swiftdoc\"," >> %/t/inputs/map.json
// RUN: echo "\"sourceInfoPath\": \"%/t/inputs/Foo.swiftsourceinfo\"" >> %/t/inputs/map.json
// RUN: echo "}," >> %/t/inputs/map.json
// RUN: echo "{" >> %/t/inputs/map.json
// RUN: echo "\"moduleName\": \"Swift\"," >> %/t/inputs/map.json
// RUN: echo "\"modulePath\": \"%stdlib_module\"," >> %/t/inputs/map.json
// RUN: echo "}," >> %/t/inputs/map.json
// RUN: echo "{" >> %/t/inputs/map.json
// RUN: echo "\"moduleName\": \"SwiftOnoneSupport\"," >> %/t/inputs/map.json
// RUN: echo "\"modulePath\": \"%ononesupport_module\"," >> %/t/inputs/map.json
// RUN: echo "}]" >> %/t/inputs/map.json

// RUN: %target-swift-ide-test -print-module-comments -module-to-print=Foo -enable-swiftsourceinfo -source-filename %s -explicit-swift-module-map-file %t/inputs/map.json | %FileCheck %s
Expand Down
8 changes: 8 additions & 0 deletions test/ScanDependencies/explicit-module-map.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@
// RUN: echo "\"modulePath\": \"%/t/inputs/Foo.swiftmodule\"," >> %/t/inputs/map.json
// RUN: echo "\"docPath\": \"%/t/inputs/Foo.swiftdoc\"," >> %/t/inputs/map.json
// RUN: echo "\"sourceInfoPath\": \"%/t/inputs/Foo.swiftsourceinfo\"" >> %/t/inputs/map.json
// RUN: echo "}," >> %/t/inputs/map.json
// RUN: echo "{" >> %/t/inputs/map.json
// RUN: echo "\"moduleName\": \"Swift\"," >> %/t/inputs/map.json
// RUN: echo "\"modulePath\": \"%stdlib_module\"," >> %/t/inputs/map.json
// RUN: echo "}," >> %/t/inputs/map.json
// RUN: echo "{" >> %/t/inputs/map.json
// RUN: echo "\"moduleName\": \"SwiftOnoneSupport\"," >> %/t/inputs/map.json
// RUN: echo "\"modulePath\": \"%ononesupport_module\"," >> %/t/inputs/map.json
// RUN: echo "}]" >> %/t/inputs/map.json

// RUN: %target-swift-ide-test -print-module-comments -module-to-print=Foo -enable-swiftsourceinfo -source-filename %s -explicit-swift-module-map-file %t/inputs/map.json | %FileCheck %s
Expand Down
20 changes: 20 additions & 0 deletions test/ScanDependencies/module_not_found.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// RUN: %empty-directory(%t)
// RUN: mkdir -p %t/clang-module-cache
// RUN: mkdir -p %t/inputs
// RUN: echo "public func foo() {}" >> %t/foo.swift
// RUN: %target-swift-frontend -emit-module -emit-module-path %t/inputs/Foo.swiftmodule -emit-module-doc-path %t/inputs/Foo.swiftdoc -emit-module-source-info -emit-module-source-info-path %t/inputs/Foo.swiftsourceinfo -module-cache-path %t.module-cache %t/foo.swift -module-name Foo

// RUN: echo "[{" >> %/t/inputs/map.json
// RUN: echo "\"moduleName\": \"Swift\"," >> %/t/inputs/map.json
// RUN: echo "\"modulePath\": \"%stdlib_dir/Swift.swiftmodule/%module-target-triple.swiftmodule\"," >> %/t/inputs/map.json
// RUN: echo "}," >> %/t/inputs/map.json
// RUN: echo "{" >> %/t/inputs/map.json
// RUN: echo "\"moduleName\": \"SwiftOnoneSupport\"," >> %/t/inputs/map.json
// RUN: echo "\"modulePath\": \"%stdlib_dir/SwiftOnoneSupport.swiftmodule/%module-target-triple.swiftmodule\"," >> %/t/inputs/map.json
// RUN: echo "}]" >> %/t/inputs/map.json

// Add the -I search path to ensure we do not accidentally implicitly load Foo.swiftmodule
// RUN: not %target-swift-frontend -typecheck %s -I %t/inputs -explicit-swift-module-map-file %t/inputs/map.json -disable-implicit-swift-modules
import Foo
// CHECK: error: no such module 'Foo'

20 changes: 20 additions & 0 deletions test/lit.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -1439,6 +1439,26 @@ config.substitutions.append(('%module-target-future', target_future))
# Add 'target-sdk-name' as the name for platform-specific directories
config.substitutions.append(('%target-sdk-name', config.target_sdk_name))

# Add 'stdlib_dir' as the path to the stdlib resource directory
stdlib_dir = config.swift_lib_dir + "/swift/"
if platform.system() == 'Linux':
stdlib_dir += config.target_sdk_name + "/" + run_cpu
else:
stdlib_dir += config.target_sdk_name
config.substitutions.append(('%stdlib_dir', stdlib_dir))

# Add 'stdlib_module' as the path to the stdlib .swiftmodule file
stdlib_module = stdlib_dir + "/Swift.swiftmodule"
if platform.system() == 'Darwin':
stdlib_module += "/" + target_specific_module_triple + ".swiftmodule"
config.substitutions.append(('%stdlib_module', stdlib_module))

# Add 'ononesupport_module' as the path to the SwiftOnoneSupport .swiftmodule file
ononesupport_module = stdlib_dir + "/SwiftOnoneSupport.swiftmodule"
if platform.system() == 'Darwin':
ononesupport_module += "/" + target_specific_module_triple + ".swiftmodule"
config.substitutions.append(('%ononesupport_module', ononesupport_module))

# Different OS's require different prefixes for the environment variables to be
# propagated to the calling contexts.
# In order to make tests OS-agnostic, names of environment variables should be
Expand Down
4 changes: 2 additions & 2 deletions tools/SourceKit/lib/SwiftLang/SwiftIndexing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,12 +211,12 @@ static void indexModule(llvm::MemoryBuffer *Input,
CompilerInstance &CI,
ArrayRef<const char *> Args) {
ASTContext &Ctx = CI.getASTContext();
std::unique_ptr<SerializedModuleLoader> Loader;
std::unique_ptr<ImplicitSerializedModuleLoader> Loader;
ModuleDecl *Mod = nullptr;
if (ModuleName == Ctx.StdlibModuleName.str()) {
Mod = Ctx.getModule({ {Ctx.StdlibModuleName, SourceLoc()} });
} else {
Loader = SerializedModuleLoader::create(Ctx);
Loader = ImplicitSerializedModuleLoader::create(Ctx);
auto Buf = std::unique_ptr<llvm::MemoryBuffer>(
llvm::MemoryBuffer::getMemBuffer(Input->getBuffer(),
Input->getBufferIdentifier()));
Expand Down