mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[NFC-ish] Simplify module loader filename handling (#29295)
* Remove dead ModuleSourceInfoFilename parameters These were never actually used; we might find a way to bring them back later. * Introduce SerializedModuleBaseName This is intended to replace the _n_ filename parameters that tend to get passed around in the SerializedModuleLoader classes. * Manipulate currPath in SerializedModuleLoader less often * Don’t pass raw paths around SerializedModuleLoader Only pass base names. * Regularize module file opening functions
This commit is contained in:
committed by
GitHub
parent
451074a426
commit
e4c1de675a
@@ -242,8 +242,9 @@ void SerializedModuleLoader::collectVisibleTopLevelModuleNames(
|
||||
names, file_types::getExtension(file_types::TY_SwiftModuleFile));
|
||||
}
|
||||
|
||||
std::error_code SerializedModuleLoaderBase::openModuleDocFile(
|
||||
AccessPathElem ModuleID, StringRef ModuleDocPath,
|
||||
std::error_code SerializedModuleLoaderBase::openModuleDocFileIfPresent(
|
||||
AccessPathElem ModuleID,
|
||||
const SerializedModuleBaseName &BaseName,
|
||||
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer) {
|
||||
|
||||
if (!ModuleDocBuffer)
|
||||
@@ -253,6 +254,9 @@ std::error_code SerializedModuleLoaderBase::openModuleDocFile(
|
||||
|
||||
// Try to open the module documentation file. If it does not exist, ignore
|
||||
// the error. However, pass though all other errors.
|
||||
SmallString<256>
|
||||
ModuleDocPath{BaseName.getName(file_types::TY_SwiftModuleDocFile)};
|
||||
|
||||
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> ModuleDocOrErr =
|
||||
FS.getBufferForFile(ModuleDocPath);
|
||||
if (ModuleDocOrErr) {
|
||||
@@ -265,40 +269,84 @@ std::error_code SerializedModuleLoaderBase::openModuleDocFile(
|
||||
return std::error_code();
|
||||
}
|
||||
|
||||
void
|
||||
std::error_code
|
||||
SerializedModuleLoaderBase::openModuleSourceInfoFileIfPresent(
|
||||
AccessPathElem ModuleID,
|
||||
StringRef ModulePath,
|
||||
StringRef ModuleSourceInfoFilename,
|
||||
const SerializedModuleBaseName &BaseName,
|
||||
std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer) {
|
||||
if (!ModuleSourceInfoBuffer)
|
||||
return;
|
||||
if (IgnoreSwiftSourceInfoFile || !ModuleSourceInfoBuffer)
|
||||
return std::error_code();
|
||||
|
||||
llvm::vfs::FileSystem &FS = *Ctx.SourceMgr.getFileSystem();
|
||||
llvm::SmallString<128> PathWithoutProjectDir(ModulePath);
|
||||
llvm::sys::path::replace_extension(PathWithoutProjectDir,
|
||||
file_types::getExtension(file_types::TY_SwiftSourceInfoFile));
|
||||
llvm::SmallString<128> PathWithProjectDir = PathWithoutProjectDir.str();
|
||||
|
||||
llvm::SmallString<128>
|
||||
PathWithoutProjectDir{BaseName.getName(file_types::TY_SwiftSourceInfoFile)};
|
||||
|
||||
llvm::SmallString<128> PathWithProjectDir = PathWithoutProjectDir;
|
||||
|
||||
// Insert "Project" before the filename in PathWithProjectDir.
|
||||
StringRef FileName = llvm::sys::path::filename(PathWithoutProjectDir);
|
||||
llvm::sys::path::remove_filename(PathWithProjectDir);
|
||||
llvm::sys::path::append(PathWithProjectDir, "Project");
|
||||
llvm::sys::path::append(PathWithProjectDir, FileName);
|
||||
|
||||
// Try to open the module source info file from the "Project" directory.
|
||||
// If it does not exist, ignore the error.
|
||||
if (auto ModuleSourceInfoOrErr = FS.getBufferForFile(PathWithProjectDir)) {
|
||||
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
|
||||
ModuleSourceInfoOrErr = FS.getBufferForFile(PathWithProjectDir);
|
||||
|
||||
// If it does not exist, try to open the module source info file adjacent to
|
||||
// the .swiftmodule file.
|
||||
if (ModuleSourceInfoOrErr.getError() == std::errc::no_such_file_or_directory)
|
||||
ModuleSourceInfoOrErr = FS.getBufferForFile(PathWithoutProjectDir);
|
||||
|
||||
// If we ended up with a different file system error, return it.
|
||||
if (ModuleSourceInfoOrErr)
|
||||
*ModuleSourceInfoBuffer = std::move(*ModuleSourceInfoOrErr);
|
||||
return;
|
||||
}
|
||||
// Try to open the module source info file adjacent to the .swiftmodule file.
|
||||
if (auto ModuleSourceInfoOrErr = FS.getBufferForFile(PathWithoutProjectDir)) {
|
||||
*ModuleSourceInfoBuffer = std::move(*ModuleSourceInfoOrErr);
|
||||
return;
|
||||
}
|
||||
else if (ModuleSourceInfoOrErr.getError() !=
|
||||
std::errc::no_such_file_or_directory)
|
||||
return ModuleSourceInfoOrErr.getError();
|
||||
|
||||
return std::error_code();
|
||||
}
|
||||
|
||||
std::error_code SerializedModuleLoaderBase::openModuleFiles(
|
||||
AccessPathElem ModuleID, StringRef ModulePath, StringRef ModuleDocPath,
|
||||
StringRef ModuleSourceInfoFileName,
|
||||
std::error_code SerializedModuleLoaderBase::openModuleFile(
|
||||
AccessPathElem ModuleID, const SerializedModuleBaseName &BaseName,
|
||||
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer) {
|
||||
llvm::vfs::FileSystem &FS = *Ctx.SourceMgr.getFileSystem();
|
||||
|
||||
// Try to open the module file first. If we fail, don't even look for the
|
||||
// module documentation file.
|
||||
SmallString<256> ModulePath{BaseName.getName(file_types::TY_SwiftModuleFile)};
|
||||
|
||||
// If there's no buffer to load into, simply check for the existence of
|
||||
// the module file.
|
||||
if (!ModuleBuffer) {
|
||||
llvm::ErrorOr<llvm::vfs::Status> statResult = FS.status(ModulePath);
|
||||
if (!statResult)
|
||||
return statResult.getError();
|
||||
|
||||
if (!statResult->exists())
|
||||
return std::make_error_code(std::errc::no_such_file_or_directory);
|
||||
|
||||
// FIXME: llvm::vfs::FileSystem doesn't give us information on whether or
|
||||
// not we can /read/ the file without actually trying to do so.
|
||||
return std::error_code();
|
||||
}
|
||||
|
||||
// Actually load the file and error out if necessary.
|
||||
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> ModuleOrErr =
|
||||
FS.getBufferForFile(ModulePath);
|
||||
if (!ModuleOrErr)
|
||||
return ModuleOrErr.getError();
|
||||
|
||||
*ModuleBuffer = std::move(ModuleOrErr.get());
|
||||
return std::error_code();
|
||||
}
|
||||
|
||||
std::error_code SerializedModuleLoader::findModuleFilesInDirectory(
|
||||
AccessPathElem ModuleID,
|
||||
const SerializedModuleBaseName &BaseName,
|
||||
SmallVectorImpl<char> *ModuleInterfacePath,
|
||||
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
|
||||
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
|
||||
std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer) {
|
||||
@@ -306,76 +354,48 @@ std::error_code SerializedModuleLoaderBase::openModuleFiles(
|
||||
(!ModuleBuffer && !ModuleDocBuffer)) &&
|
||||
"Module and Module Doc buffer must both be initialized or NULL");
|
||||
|
||||
llvm::vfs::FileSystem &FS = *Ctx.SourceMgr.getFileSystem();
|
||||
if (LoadMode == ModuleLoadingMode::OnlyInterface)
|
||||
return std::make_error_code(std::errc::not_supported);
|
||||
|
||||
// Try to open the module file first. If we fail, don't even look for the
|
||||
// module documentation file.
|
||||
auto ModuleErr = openModuleFile(ModuleID, BaseName, ModuleBuffer);
|
||||
if (ModuleErr)
|
||||
return ModuleErr;
|
||||
|
||||
// If there are no buffers to load into, simply check for the existence of
|
||||
// the module file.
|
||||
if (!(ModuleBuffer || ModuleDocBuffer)) {
|
||||
llvm::ErrorOr<llvm::vfs::Status> statResult = FS.status(ModulePath);
|
||||
if (!statResult)
|
||||
return statResult.getError();
|
||||
if (!statResult->exists())
|
||||
return std::make_error_code(std::errc::no_such_file_or_directory);
|
||||
// FIXME: llvm::vfs::FileSystem doesn't give us information on whether or
|
||||
// not we can /read/ the file without actually trying to do so.
|
||||
return std::error_code();
|
||||
// If there are no buffers to load into, all we care about is whether the
|
||||
// module file existed.
|
||||
if (ModuleBuffer || ModuleDocBuffer || ModuleSourceInfoBuffer) {
|
||||
auto ModuleSourceInfoError = openModuleSourceInfoFileIfPresent(
|
||||
ModuleID, BaseName, ModuleSourceInfoBuffer
|
||||
);
|
||||
if (ModuleSourceInfoError)
|
||||
return ModuleSourceInfoError;
|
||||
|
||||
auto ModuleDocErr = openModuleDocFileIfPresent(
|
||||
ModuleID, BaseName, ModuleDocBuffer
|
||||
);
|
||||
if (ModuleDocErr)
|
||||
return ModuleDocErr;
|
||||
}
|
||||
|
||||
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> ModuleOrErr =
|
||||
FS.getBufferForFile(ModulePath);
|
||||
if (!ModuleOrErr)
|
||||
return ModuleOrErr.getError();
|
||||
if (!IgnoreSwiftSourceInfoFile) {
|
||||
// Open .swiftsourceinfo file if it's present.
|
||||
openModuleSourceInfoFileIfPresent(ModuleID, ModulePath,
|
||||
ModuleSourceInfoFileName,
|
||||
ModuleSourceInfoBuffer);
|
||||
}
|
||||
auto ModuleDocErr =
|
||||
openModuleDocFile(ModuleID, ModuleDocPath, ModuleDocBuffer);
|
||||
if (ModuleDocErr)
|
||||
return ModuleDocErr;
|
||||
|
||||
*ModuleBuffer = std::move(ModuleOrErr.get());
|
||||
|
||||
return std::error_code();
|
||||
}
|
||||
|
||||
std::error_code SerializedModuleLoader::findModuleFilesInDirectory(
|
||||
AccessPathElem ModuleID, StringRef DirPath, StringRef ModuleFilename,
|
||||
StringRef ModuleDocFilename, StringRef ModuleSourceInfoFileName,
|
||||
SmallVectorImpl<char> *ModuleInterfacePath,
|
||||
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
|
||||
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
|
||||
std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer) {
|
||||
if (LoadMode == ModuleLoadingMode::OnlyInterface)
|
||||
return std::make_error_code(std::errc::not_supported);
|
||||
|
||||
llvm::SmallString<256> ModulePath{DirPath};
|
||||
llvm::sys::path::append(ModulePath, ModuleFilename);
|
||||
llvm::SmallString<256> ModuleDocPath{DirPath};
|
||||
llvm::sys::path::append(ModuleDocPath, ModuleDocFilename);
|
||||
return SerializedModuleLoaderBase::openModuleFiles(ModuleID,
|
||||
ModulePath,
|
||||
ModuleDocPath,
|
||||
ModuleSourceInfoFileName,
|
||||
ModuleBuffer,
|
||||
ModuleDocBuffer,
|
||||
ModuleSourceInfoBuffer);
|
||||
}
|
||||
|
||||
bool SerializedModuleLoader::maybeDiagnoseTargetMismatch(
|
||||
SourceLoc sourceLocation, StringRef moduleName, StringRef archName,
|
||||
StringRef directoryPath) {
|
||||
SourceLoc sourceLocation, StringRef moduleName,
|
||||
const SerializedModuleBaseName &absoluteBaseName) {
|
||||
llvm::vfs::FileSystem &fs = *Ctx.SourceMgr.getFileSystem();
|
||||
|
||||
// Get the last component of the base name, which is the target-specific one.
|
||||
auto target = llvm::sys::path::filename(absoluteBaseName.baseName);
|
||||
|
||||
// Strip off the last component to get the .swiftmodule folder.
|
||||
auto dir = absoluteBaseName.baseName;
|
||||
llvm::sys::path::remove_filename(dir);
|
||||
|
||||
std::error_code errorCode;
|
||||
std::string foundArchs;
|
||||
for (llvm::vfs::directory_iterator directoryIterator =
|
||||
fs.dir_begin(directoryPath, errorCode), endIterator;
|
||||
fs.dir_begin(dir, errorCode), endIterator;
|
||||
directoryIterator != endIterator;
|
||||
directoryIterator.increment(errorCode)) {
|
||||
if (errorCode)
|
||||
@@ -398,28 +418,23 @@ bool SerializedModuleLoader::maybeDiagnoseTargetMismatch(
|
||||
}
|
||||
|
||||
Ctx.Diags.diagnose(sourceLocation, diag::sema_no_import_target, moduleName,
|
||||
archName, foundArchs);
|
||||
target, foundArchs);
|
||||
return true;
|
||||
}
|
||||
|
||||
struct ModuleFilenamePair {
|
||||
llvm::SmallString<64> module;
|
||||
llvm::SmallString<64> moduleDoc;
|
||||
llvm::SmallString<64> moduleSourceInfo;
|
||||
SerializedModuleBaseName::SerializedModuleBaseName(
|
||||
StringRef parentDir, const SerializedModuleBaseName &name)
|
||||
: baseName(parentDir) {
|
||||
llvm::sys::path::append(baseName, name.baseName);
|
||||
}
|
||||
|
||||
ModuleFilenamePair(StringRef baseName)
|
||||
: module(baseName), moduleDoc(baseName), moduleSourceInfo(baseName)
|
||||
{
|
||||
module += '.';
|
||||
module += file_types::getExtension(file_types::TY_SwiftModuleFile);
|
||||
std::string SerializedModuleBaseName::getName(file_types::ID fileTy) const {
|
||||
auto result = baseName;
|
||||
result += '.';
|
||||
result += file_types::getExtension(fileTy);
|
||||
|
||||
moduleDoc += '.';
|
||||
moduleDoc += file_types::getExtension(file_types::TY_SwiftModuleDocFile);
|
||||
|
||||
moduleSourceInfo += '.';
|
||||
moduleSourceInfo += file_types::getExtension(file_types::TY_SwiftSourceInfoFile);
|
||||
}
|
||||
};
|
||||
return result.str();
|
||||
}
|
||||
|
||||
bool
|
||||
SerializedModuleLoaderBase::findModule(AccessPathElem moduleID,
|
||||
@@ -428,15 +443,19 @@ SerializedModuleLoaderBase::findModule(AccessPathElem moduleID,
|
||||
std::unique_ptr<llvm::MemoryBuffer> *moduleDocBuffer,
|
||||
std::unique_ptr<llvm::MemoryBuffer> *moduleSourceInfoBuffer,
|
||||
bool &isFramework, bool &isSystemModule) {
|
||||
llvm::SmallString<64> moduleName(moduleID.Item.str());
|
||||
ModuleFilenamePair fileNames(moduleName);
|
||||
SmallString<32> moduleName(moduleID.Item.str());
|
||||
SerializedModuleBaseName genericBaseName(moduleName);
|
||||
|
||||
SmallVector<ModuleFilenamePair, 4> targetFileNamePairs;
|
||||
SmallString<32> primaryTargetSpecificName;
|
||||
auto genericModuleFileName =
|
||||
genericBaseName.getName(file_types::TY_SwiftModuleFile);
|
||||
|
||||
SmallVector<SerializedModuleBaseName, 4> targetSpecificBaseNames;
|
||||
forEachTargetModuleBasename(Ctx, [&](StringRef targetName) {
|
||||
targetFileNamePairs.emplace_back(targetName);
|
||||
if (primaryTargetSpecificName.empty())
|
||||
primaryTargetSpecificName = targetName;
|
||||
// Construct a base name like ModuleName.swiftmodule/arch-vendor-os
|
||||
SmallString<64> targetBaseName{genericModuleFileName};
|
||||
llvm::sys::path::append(targetBaseName, targetName);
|
||||
|
||||
targetSpecificBaseNames.emplace_back(targetBaseName.str());
|
||||
});
|
||||
|
||||
auto &fs = *Ctx.SourceMgr.getFileSystem();
|
||||
@@ -447,10 +466,17 @@ SerializedModuleLoaderBase::findModule(AccessPathElem moduleID,
|
||||
/// was diagnosed, or None if neither one happened and the search should
|
||||
/// continue.
|
||||
auto findTargetSpecificModuleFiles = [&]() -> Optional<bool> {
|
||||
for (const auto &targetFileNames : targetFileNamePairs) {
|
||||
auto result = findModuleFilesInDirectory(moduleID, currPath,
|
||||
targetFileNames.module, targetFileNames.moduleDoc,
|
||||
targetFileNames.moduleSourceInfo,
|
||||
Optional<SerializedModuleBaseName> firstAbsoluteBaseName;
|
||||
|
||||
for (const auto &targetSpecificBaseName : targetSpecificBaseNames) {
|
||||
SerializedModuleBaseName
|
||||
absoluteBaseName{currPath, targetSpecificBaseName};
|
||||
|
||||
if (!firstAbsoluteBaseName.hasValue())
|
||||
firstAbsoluteBaseName.emplace(absoluteBaseName);
|
||||
|
||||
auto result = findModuleFilesInDirectory(moduleID,
|
||||
absoluteBaseName,
|
||||
moduleInterfacePath,
|
||||
moduleBuffer, moduleDocBuffer,
|
||||
moduleSourceInfoBuffer);
|
||||
@@ -465,8 +491,9 @@ SerializedModuleLoaderBase::findModule(AccessPathElem moduleID,
|
||||
|
||||
// We can only get here if all targetFileNamePairs failed with
|
||||
// 'std::errc::no_such_file_or_directory'.
|
||||
if (maybeDiagnoseTargetMismatch(moduleID.Loc, moduleName,
|
||||
primaryTargetSpecificName, currPath)) {
|
||||
if (firstAbsoluteBaseName
|
||||
&& maybeDiagnoseTargetMismatch(moduleID.Loc, moduleName,
|
||||
*firstAbsoluteBaseName)) {
|
||||
return false;
|
||||
} else {
|
||||
return None;
|
||||
@@ -484,7 +511,6 @@ SerializedModuleLoaderBase::findModule(AccessPathElem moduleID,
|
||||
case SearchPathKind::Import:
|
||||
case SearchPathKind::RuntimeLibrary: {
|
||||
isFramework = false;
|
||||
llvm::sys::path::append(currPath, fileNames.module.str());
|
||||
|
||||
bool checkTargetSpecificModule;
|
||||
if (Kind == SearchPathKind::RuntimeLibrary) {
|
||||
@@ -493,7 +519,10 @@ SerializedModuleLoaderBase::findModule(AccessPathElem moduleID,
|
||||
// always use single-architecture swiftmodules.
|
||||
checkTargetSpecificModule = Ctx.LangOpts.Target.isOSDarwin();
|
||||
} else {
|
||||
llvm::ErrorOr<llvm::vfs::Status> statResult = fs.status(currPath);
|
||||
auto modulePath = currPath;
|
||||
llvm::sys::path::append(modulePath, genericModuleFileName);
|
||||
|
||||
llvm::ErrorOr<llvm::vfs::Status> statResult = fs.status(modulePath);
|
||||
// Even if stat fails, we can't just return the error; the path
|
||||
// we're looking for might not be "Foo.swiftmodule".
|
||||
checkTargetSpecificModule = statResult && statResult->isDirectory();
|
||||
@@ -503,9 +532,10 @@ SerializedModuleLoaderBase::findModule(AccessPathElem moduleID,
|
||||
// A .swiftmodule directory contains architecture-specific files.
|
||||
return findTargetSpecificModuleFiles();
|
||||
|
||||
SerializedModuleBaseName absoluteBaseName{currPath, genericBaseName};
|
||||
|
||||
auto result = findModuleFilesInDirectory(
|
||||
moduleID, path, fileNames.module.str(), fileNames.moduleDoc.str(),
|
||||
fileNames.moduleSourceInfo.str(), moduleInterfacePath,
|
||||
moduleID, absoluteBaseName, moduleInterfacePath,
|
||||
moduleBuffer, moduleDocBuffer, moduleSourceInfoBuffer);
|
||||
if (!result)
|
||||
return true;
|
||||
@@ -516,8 +546,7 @@ SerializedModuleLoaderBase::findModule(AccessPathElem moduleID,
|
||||
}
|
||||
case SearchPathKind::Framework: {
|
||||
isFramework = true;
|
||||
llvm::sys::path::append(currPath,
|
||||
moduleID.Item.str() + ".framework");
|
||||
llvm::sys::path::append(currPath, moduleName + ".framework");
|
||||
|
||||
// Check if the framework directory exists.
|
||||
if (!fs.exists(currPath))
|
||||
@@ -525,7 +554,7 @@ SerializedModuleLoaderBase::findModule(AccessPathElem moduleID,
|
||||
|
||||
// Frameworks always use architecture-specific files within a
|
||||
// .swiftmodule directory.
|
||||
llvm::sys::path::append(currPath, "Modules", fileNames.module.str());
|
||||
llvm::sys::path::append(currPath, "Modules");
|
||||
return findTargetSpecificModuleFiles();
|
||||
}
|
||||
}
|
||||
@@ -956,8 +985,8 @@ void SerializedModuleLoaderBase::loadObjCMethods(
|
||||
}
|
||||
|
||||
std::error_code MemoryBufferSerializedModuleLoader::findModuleFilesInDirectory(
|
||||
AccessPathElem ModuleID, StringRef DirPath, StringRef ModuleFilename,
|
||||
StringRef ModuleDocFilename, StringRef ModuleSourceInfoFilename,
|
||||
AccessPathElem ModuleID,
|
||||
const SerializedModuleBaseName &BaseName,
|
||||
SmallVectorImpl<char> *ModuleInterfacePath,
|
||||
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
|
||||
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
|
||||
@@ -970,8 +999,8 @@ std::error_code MemoryBufferSerializedModuleLoader::findModuleFilesInDirectory(
|
||||
}
|
||||
|
||||
bool MemoryBufferSerializedModuleLoader::maybeDiagnoseTargetMismatch(
|
||||
SourceLoc sourceLocation, StringRef moduleName, StringRef archName,
|
||||
StringRef directoryPath) {
|
||||
SourceLoc sourceLocation, StringRef moduleName,
|
||||
const SerializedModuleBaseName &absoluteBaseName) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user