Do not build Swift interface files into binary modules when performing a canImport query.

We should hold off actually building the binary module file until it is imported.
`canImport` queries can happen, for example, during dependency scanning, when we do not wish to have the scanner tool execute any module builds.

Resolves rdar://82603098
This commit is contained in:
Artem Chikin
2021-09-01 16:06:21 -07:00
parent 1907a820ea
commit 1b7d55582d
9 changed files with 50 additions and 22 deletions

View File

@@ -423,7 +423,7 @@ std::error_code ImplicitSerializedModuleLoader::findModuleFilesInDirectory(
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer,
bool IsFramework) {
bool skipBuildingInterface, bool IsFramework) {
assert(((ModuleBuffer && ModuleDocBuffer) ||
(!ModuleBuffer && !ModuleDocBuffer)) &&
"Module and Module Doc buffer must both be initialized or NULL");
@@ -516,7 +516,7 @@ SerializedModuleLoaderBase::findModule(ImportPath::Element moduleID,
std::unique_ptr<llvm::MemoryBuffer> *moduleBuffer,
std::unique_ptr<llvm::MemoryBuffer> *moduleDocBuffer,
std::unique_ptr<llvm::MemoryBuffer> *moduleSourceInfoBuffer,
bool &isFramework, bool &isSystemModule) {
bool skipBuildingInterface, bool &isFramework, bool &isSystemModule) {
SmallString<32> moduleName(moduleID.Item.str());
SerializedModuleBaseName genericBaseName(moduleName);
@@ -554,6 +554,7 @@ SerializedModuleLoaderBase::findModule(ImportPath::Element moduleID,
moduleInterfacePath,
moduleBuffer, moduleDocBuffer,
moduleSourceInfoBuffer,
skipBuildingInterface,
IsFramework);
if (!result) {
return true;
@@ -611,7 +612,8 @@ SerializedModuleLoaderBase::findModule(ImportPath::Element moduleID,
auto result = findModuleFilesInDirectory(
moduleID, absoluteBaseName, moduleInterfacePath,
moduleBuffer, moduleDocBuffer, moduleSourceInfoBuffer, isFramework);
moduleBuffer, moduleDocBuffer, moduleSourceInfoBuffer,
skipBuildingInterface, isFramework);
if (!result)
return true;
else if (result == std::errc::not_supported)
@@ -1067,7 +1069,8 @@ bool SerializedModuleLoaderBase::canImportModule(
auto found = findModule(mID, unusedModuleInterfacePath, unusedModuleBuffer,
unusedModuleDocBuffer, unusedModuleSourceInfoBuffer,
isFramework, isSystemModule);
/* skipBuildingInterface */ true, isFramework,
isSystemModule);
// If we cannot find the module, don't continue.
if (!found)
return false;
@@ -1083,7 +1086,7 @@ bool SerializedModuleLoaderBase::canImportModule(
}
// If failing to extract the user version from the interface file, try the binary
// format, if present.
if (currentVersion.empty() && unusedModuleBuffer) {
if (currentVersion.empty() && *unusedModuleBuffer) {
auto metaData =
serialization::validateSerializedAST((*unusedModuleBuffer)->getBuffer());
currentVersion = metaData.userModuleVersion;
@@ -1137,7 +1140,7 @@ SerializedModuleLoaderBase::loadModule(SourceLoc importLoc,
// Look on disk.
if (!findModule(moduleID, &moduleInterfacePath, &moduleInputBuffer,
&moduleDocInputBuffer, &moduleSourceInfoInputBuffer,
isFramework, isSystemModule)) {
/* skipBuildingInterface */ false, isFramework, isSystemModule)) {
return nullptr;
}
@@ -1251,7 +1254,7 @@ std::error_code MemoryBufferSerializedModuleLoader::findModuleFilesInDirectory(
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer,
bool IsFramework) {
bool skipBuildingInterface, bool IsFramework) {
// 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.