Factor out the pre-registered MemoryBuffer functionality

form SerializedModuleLoader into its own ModuleLoader class. (NFC-ish)

This gives better control over the order in which the various module
load mechanisms are applied.
This commit is contained in:
Adrian Prantl
2019-04-19 15:18:19 -07:00
parent 007fbb6ebd
commit b244b0928e
8 changed files with 165 additions and 66 deletions

View File

@@ -35,13 +35,14 @@ namespace {
} // end unnamed namespace
// Defined out-of-line so that we can see ~ModuleFile.
SerializedModuleLoaderBase::SerializedModuleLoaderBase(ASTContext &ctx,
DependencyTracker *tracker,
ModuleLoadingMode loadMode)
: ModuleLoader(tracker), Ctx(ctx), LoadMode(loadMode) {}
SerializedModuleLoaderBase::~SerializedModuleLoaderBase() = default;
SerializedModuleLoaderBase::SerializedModuleLoaderBase(
ASTContext &ctx, DependencyTracker *tracker, ModuleLoadingMode loadMode)
: ModuleLoader(tracker), Ctx(ctx), LoadMode(loadMode) {}
SerializedModuleLoaderBase::~SerializedModuleLoaderBase() = default;
SerializedModuleLoader::~SerializedModuleLoader() = default;
MemoryBufferSerializedModuleLoader::~MemoryBufferSerializedModuleLoader() =
default;
std::error_code SerializedModuleLoaderBase::openModuleDocFile(
AccessPathElem ModuleID, StringRef ModuleDocPath,
@@ -607,23 +608,22 @@ void swift::serialization::diagnoseSerializedASTLoadFailure(
}
}
bool
SerializedModuleLoaderBase::canImportModule(std::pair<Identifier, SourceLoc> mID) {
// First see if we find it in the registered memory buffers.
if (!MemoryBuffers.empty()) {
auto bufIter = MemoryBuffers.find(mID.first.str());
if (bufIter != MemoryBuffers.end()) {
return true;
}
}
// Otherwise look on disk.
bool SerializedModuleLoaderBase::canImportModule(
std::pair<Identifier, SourceLoc> mID) {
// Look on disk.
bool isFramework = false;
return findModule(mID, nullptr, nullptr, isFramework);
}
ModuleDecl *SerializedModuleLoaderBase::loadModule(SourceLoc importLoc,
ModuleDecl::AccessPathTy path) {
bool MemoryBufferSerializedModuleLoader::canImportModule(
std::pair<Identifier, SourceLoc> mID) {
// See if we find it in the registered memory buffers.
return MemoryBuffers.count(mID.first.str());
}
ModuleDecl *
SerializedModuleLoaderBase::loadModule(SourceLoc importLoc,
ModuleDecl::AccessPathTy path) {
// FIXME: Swift submodules?
if (path.size() > 1)
return nullptr;
@@ -633,30 +633,17 @@ ModuleDecl *SerializedModuleLoaderBase::loadModule(SourceLoc importLoc,
std::unique_ptr<llvm::MemoryBuffer> moduleInputBuffer;
std::unique_ptr<llvm::MemoryBuffer> moduleDocInputBuffer;
// First see if we find it in the registered memory buffers.
if (!MemoryBuffers.empty()) {
// FIXME: Right now this works only with access paths of length 1.
// Once submodules are designed, this needs to support suffix
// matching and a search path.
auto bufIter = MemoryBuffers.find(moduleID.first.str());
if (bufIter != MemoryBuffers.end()) {
moduleInputBuffer = std::move(bufIter->second);
MemoryBuffers.erase(bufIter);
}
}
// Otherwise look on disk.
if (!moduleInputBuffer) {
if (!findModule(moduleID, &moduleInputBuffer, &moduleDocInputBuffer,
isFramework)) {
return nullptr;
}
if (dependencyTracker) {
// Don't record cached artifacts as dependencies.
StringRef DepPath = moduleInputBuffer->getBufferIdentifier();
if (!isCached(DepPath)) {
dependencyTracker->addDependency(DepPath, /*isSystem=*/false);
}
// Look on disk.
if (!findModule(moduleID, &moduleInputBuffer, &moduleDocInputBuffer,
isFramework)) {
return nullptr;
}
if (dependencyTracker) {
// Don't record cached artifacts as dependencies.
StringRef DepPath = moduleInputBuffer->getBufferIdentifier();
if (!isCached(DepPath)) {
dependencyTracker->addDependency(DepPath, /*isSystem=*/false);
}
}
@@ -675,6 +662,43 @@ ModuleDecl *SerializedModuleLoaderBase::loadModule(SourceLoc importLoc,
return M;
}
ModuleDecl *
MemoryBufferSerializedModuleLoader::loadModule(SourceLoc importLoc,
ModuleDecl::AccessPathTy path) {
// FIXME: Swift submodules?
if (path.size() > 1)
return nullptr;
auto moduleID = path[0];
// See if we find it in the registered memory buffers.
// FIXME: Right now this works only with access paths of length 1.
// Once submodules are designed, this needs to support suffix
// matching and a search path.
auto bufIter = MemoryBuffers.find(moduleID.first.str());
if (bufIter == MemoryBuffers.end())
return nullptr;
bool isFramework = false;
bool treatAsPartialModule = false;
std::unique_ptr<llvm::MemoryBuffer> moduleInputBuffer;
moduleInputBuffer = std::move(bufIter->second);
MemoryBuffers.erase(bufIter);
assert(moduleInputBuffer);
auto *M = ModuleDecl::create(moduleID.first, Ctx);
SWIFT_DEFER { M->setHasResolvedImports(); };
if (!loadAST(*M, moduleID.second, std::move(moduleInputBuffer), {},
isFramework, treatAsPartialModule)) {
return nullptr;
}
Ctx.LoadedModules[moduleID.first] = M;
return M;
}
void SerializedModuleLoaderBase::loadExtensions(NominalTypeDecl *nominal,
unsigned previousGeneration) {
for (auto &modulePair : LoadedModuleFiles) {
@@ -698,6 +722,24 @@ void SerializedModuleLoaderBase::loadObjCMethods(
}
}
std::error_code MemoryBufferSerializedModuleLoader::findModuleFilesInDirectory(
AccessPathElem ModuleID, StringRef DirPath, StringRef ModuleFilename,
StringRef ModuleDocFilename,
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer) {
// This is a soft error instead of an llvm_unreachable because this API is
// primarily used by LLDB which makes it more likely that unwitting changes to
// the Swift compiler accidentally break the contract.
assert(false && "not supported");
return std::make_error_code(std::errc::not_supported);
}
bool MemoryBufferSerializedModuleLoader::maybeDiagnoseTargetMismatch(
SourceLoc sourceLocation, StringRef moduleName, StringRef archName,
StringRef directoryPath) {
return false;
}
void SerializedModuleLoaderBase::verifyAllModules() {
#ifndef NDEBUG
for (const LoadedModulePair &loaded : LoadedModuleFiles)