[Dependency Scanning] Add support for diagnosing invalid architecture swift binary module candidates

Refactor 'maybeDiagnoseTargetMismatch' to separately collect mismatching target variant modules in 'identifyArchitectureVariants' and rename it to 'handlePossibleTargetMismatch'.

Prior uses of 'maybeDiagnoseTargetMismatch' will continue diagnosing errors/warnings on only discovering incompatible swift binary module target variants.

A new overload of 'handlePossibleTargetMismatch', in 'SwiftModuleScanner', instead collects it as a discovered incompatible candidate, for diagnosis downstream.
This commit is contained in:
Artem Chikin
2025-09-23 15:36:11 -07:00
parent c73869e479
commit 48c2a328ec
5 changed files with 76 additions and 23 deletions

View File

@@ -577,47 +577,58 @@ std::error_code ImplicitSerializedModuleLoader::findModuleFilesInDirectory(
return std::error_code();
}
bool ImplicitSerializedModuleLoader::maybeDiagnoseTargetMismatch(
SourceLoc sourceLocation, StringRef moduleName,
const SerializedModuleBaseName &absoluteBaseName,
bool isCanImportLookup) {
void SerializedModuleLoaderBase::identifyArchitectureVariants(
ASTContext &Ctx, const SerializedModuleBaseName &absoluteBaseName,
std::vector<std::string> &incompatibleArchModules) {
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(dir, errorCode), endIterator;
directoryIterator != endIterator;
directoryIterator.increment(errorCode)) {
if (errorCode)
return false;
continue;
StringRef filePath = directoryIterator->path();
StringRef extension = llvm::sys::path::extension(filePath);
if (file_types::lookupTypeForExtension(extension) ==
file_types::TY_SwiftModuleFile) {
if (!foundArchs.empty())
foundArchs += ", ";
foundArchs += llvm::sys::path::stem(filePath).str();
incompatibleArchModules.push_back(filePath.str());
}
}
}
if (foundArchs.empty()) {
// Maybe this swiftmodule directory only contains swiftinterfaces, or
// maybe something else is going on. Regardless, we shouldn't emit a
// possibly incorrect diagnostic.
bool ImplicitSerializedModuleLoader::handlePossibleTargetMismatch(
SourceLoc sourceLocation, StringRef moduleName,
const SerializedModuleBaseName &absoluteBaseName,
bool isCanImportLookup) {
std::string foundArchs;
std::vector<std::string> foundIncompatibleArchModules;
identifyArchitectureVariants(Ctx, absoluteBaseName,
foundIncompatibleArchModules);
// Maybe this swiftmodule directory only contains swiftinterfaces, or
// maybe something else is going on. Regardless, we shouldn't emit a
// possibly incorrect diagnostic.
if (foundIncompatibleArchModules.empty())
return false;
// Generate combined list of discovered architectures
// for the diagnostic
for (const auto &modulePath : foundIncompatibleArchModules) {
if (!foundArchs.empty())
foundArchs += ", ";
foundArchs += llvm::sys::path::stem(modulePath).str();
}
Ctx.Diags
.diagnose(sourceLocation, diag::sema_no_import_target, moduleName, target,
foundArchs, dir)
.diagnose(sourceLocation, diag::sema_no_import_target, moduleName,
llvm::sys::path::filename(absoluteBaseName.baseName),
foundArchs, absoluteBaseName.baseName)
.limitBehaviorIf(isCanImportLookup, DiagnosticBehavior::Warning);
return !isCanImportLookup;
}
@@ -782,8 +793,8 @@ bool SerializedModuleLoaderBase::findModule(
// We can only get here if all targetFileNamePairs failed with
// 'std::errc::no_such_file_or_directory'.
if (firstAbsoluteBaseName &&
maybeDiagnoseTargetMismatch(moduleID.Loc, moduleName,
*firstAbsoluteBaseName, isCanImportLookup))
handlePossibleTargetMismatch(moduleID.Loc, moduleName,
*firstAbsoluteBaseName, isCanImportLookup))
return SearchResult::Error;
return SearchResult::NotFound;