mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[Dependency Scanning] Move generation of a named import path 'Identifier' out of the individual scanning workers up into the parent scanner. This operation mutates the scanner ASTContext by potentially adding new identifiers to it and is therefore not thread-safe.
This commit is contained in:
@@ -341,7 +341,7 @@ public:
|
||||
/// Retrieve the dependencies for the given, named module, or \c None
|
||||
/// if no such module exists.
|
||||
virtual llvm::SmallVector<std::pair<ModuleDependencyID, ModuleDependencyInfo>, 1>
|
||||
getModuleDependencies(StringRef moduleName,
|
||||
getModuleDependencies(Identifier moduleName,
|
||||
StringRef moduleOutputPath,
|
||||
llvm::IntrusiveRefCntPtr<llvm::cas::CachingOnDiskFileSystem> CacheFS,
|
||||
const llvm::DenseSet<clang::tooling::dependencies::ModuleID> &alreadySeenClangModules,
|
||||
|
||||
@@ -440,7 +440,7 @@ public:
|
||||
StringRef moduleOutputPath, RemapPathCallback remapPath = nullptr);
|
||||
|
||||
llvm::SmallVector<std::pair<ModuleDependencyID, ModuleDependencyInfo>, 1>
|
||||
getModuleDependencies(StringRef moduleName, StringRef moduleOutputPath,
|
||||
getModuleDependencies(Identifier moduleName, StringRef moduleOutputPath,
|
||||
llvm::IntrusiveRefCntPtr<llvm::cas::CachingOnDiskFileSystem> CacheFS,
|
||||
const llvm::DenseSet<clang::tooling::dependencies::ModuleID> &alreadySeenClangModules,
|
||||
clang::tooling::dependencies::DependencyScanningTool &clangScanningTool,
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "swift/AST/ASTContext.h"
|
||||
#include "swift/AST/Identifier.h"
|
||||
#include "swift/AST/ModuleDependencies.h"
|
||||
#include "swift/Frontend/ModuleInterfaceLoader.h"
|
||||
#include "swift/Serialization/SerializedModuleLoader.h"
|
||||
@@ -36,18 +37,18 @@ public:
|
||||
private:
|
||||
/// Retrieve the module dependencies for the module with the given name.
|
||||
ModuleDependencyVector
|
||||
scanFilesystemForModuleDependency(StringRef moduleName,
|
||||
scanFilesystemForModuleDependency(Identifier moduleName,
|
||||
const ModuleDependenciesCache &cache,
|
||||
bool isTestableImport = false);
|
||||
|
||||
/// Retrieve the module dependencies for the Clang module with the given name.
|
||||
ModuleDependencyVector
|
||||
scanFilesystemForClangModuleDependency(StringRef moduleName,
|
||||
scanFilesystemForClangModuleDependency(Identifier moduleName,
|
||||
const ModuleDependenciesCache &cache);
|
||||
|
||||
/// Retrieve the module dependencies for the Swift module with the given name.
|
||||
ModuleDependencyVector
|
||||
scanFilesystemForSwiftModuleDependency(StringRef moduleName,
|
||||
scanFilesystemForSwiftModuleDependency(Identifier moduleName,
|
||||
const ModuleDependenciesCache &cache);
|
||||
|
||||
// An AST delegate for interface scanning.
|
||||
@@ -135,6 +136,8 @@ private:
|
||||
template <typename Function, typename... Args>
|
||||
auto withDependencyScanningWorker(Function &&F, Args &&...ArgList);
|
||||
|
||||
Identifier getModuleImportIdentifier(StringRef moduleName);
|
||||
|
||||
private:
|
||||
const CompilerInvocation &ScanCompilerInvocation;
|
||||
ASTContext &ScanASTContext;
|
||||
|
||||
@@ -98,7 +98,7 @@ public:
|
||||
}
|
||||
|
||||
llvm::SmallVector<std::pair<ModuleDependencyID, ModuleDependencyInfo>, 1>
|
||||
getModuleDependencies(StringRef moduleName, StringRef moduleOutputPath,
|
||||
getModuleDependencies(Identifier moduleName, StringRef moduleOutputPath,
|
||||
llvm::IntrusiveRefCntPtr<llvm::cas::CachingOnDiskFileSystem> CacheFS,
|
||||
const llvm::DenseSet<clang::tooling::dependencies::ModuleID> &alreadySeenClangModules,
|
||||
clang::tooling::dependencies::DependencyScanningTool &clangScanningTool,
|
||||
|
||||
@@ -250,7 +250,7 @@ public:
|
||||
virtual void verifyAllModules() override;
|
||||
|
||||
virtual llvm::SmallVector<std::pair<ModuleDependencyID, ModuleDependencyInfo>, 1>
|
||||
getModuleDependencies(StringRef moduleName, StringRef moduleOutputPath,
|
||||
getModuleDependencies(Identifier moduleName, StringRef moduleOutputPath,
|
||||
llvm::IntrusiveRefCntPtr<llvm::cas::CachingOnDiskFileSystem> CacheFS,
|
||||
const llvm::DenseSet<clang::tooling::dependencies::ModuleID> &alreadySeenClangModules,
|
||||
clang::tooling::dependencies::DependencyScanningTool &clangScanningTool,
|
||||
|
||||
@@ -101,10 +101,12 @@ ModuleSearchPathLookup::searchPathsContainingFile(
|
||||
llvm::SmallSet<std::pair<ModuleSearchPathKind, unsigned>, 4> ResultIds;
|
||||
|
||||
for (auto &Filename : Filenames) {
|
||||
for (auto &Entry : LookupTable.lookup(Filename)) {
|
||||
if (ResultIds.insert(std::make_pair(Entry->getKind(), Entry->getIndex()))
|
||||
.second) {
|
||||
Result.push_back(Entry.get());
|
||||
if (LookupTable.contains(Filename)) {
|
||||
for (auto &Entry : LookupTable.at(Filename)) {
|
||||
if (ResultIds.insert(std::make_pair(Entry->getKind(), Entry->getIndex()))
|
||||
.second) {
|
||||
Result.push_back(Entry.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -407,7 +407,7 @@ computeClangWorkingDirectory(const std::vector<std::string> &commandLineArgs,
|
||||
}
|
||||
|
||||
ModuleDependencyVector
|
||||
ClangImporter::getModuleDependencies(StringRef moduleName,
|
||||
ClangImporter::getModuleDependencies(Identifier moduleName,
|
||||
StringRef moduleOutputPath,
|
||||
llvm::IntrusiveRefCntPtr<llvm::cas::CachingOnDiskFileSystem> CacheFS,
|
||||
const llvm::DenseSet<clang::tooling::dependencies::ModuleID> &alreadySeenClangModules,
|
||||
@@ -435,14 +435,14 @@ ClangImporter::getModuleDependencies(StringRef moduleName,
|
||||
|
||||
auto clangModuleDependencies =
|
||||
clangScanningTool.getModuleDependencies(
|
||||
moduleName, commandLineArgs, workingDir,
|
||||
moduleName.str(), commandLineArgs, workingDir,
|
||||
alreadySeenClangModules, lookupModuleOutput);
|
||||
if (!clangModuleDependencies) {
|
||||
auto errorStr = toString(clangModuleDependencies.takeError());
|
||||
// We ignore the "module 'foo' not found" error, the Swift dependency
|
||||
// scanner will report such an error only if all of the module loaders
|
||||
// fail as well.
|
||||
if (errorStr.find("fatal error: module '" + moduleName.str() +
|
||||
if (errorStr.find("fatal error: module '" + moduleName.str().str() +
|
||||
"' not found") == std::string::npos)
|
||||
ctx.Diags.diagnose(SourceLoc(), diag::clang_dependency_scan_error,
|
||||
errorStr);
|
||||
|
||||
@@ -179,7 +179,7 @@ ModuleDependencyScanningWorker::ModuleDependencyScanningWorker(
|
||||
|
||||
ModuleDependencyVector
|
||||
ModuleDependencyScanningWorker::scanFilesystemForModuleDependency(
|
||||
StringRef moduleName, const ModuleDependenciesCache &cache,
|
||||
Identifier moduleName, const ModuleDependenciesCache &cache,
|
||||
bool isTestableImport) {
|
||||
// First query a Swift module, otherwise lookup a Clang module
|
||||
ModuleDependencyVector moduleDependencies =
|
||||
@@ -203,7 +203,7 @@ ModuleDependencyScanningWorker::scanFilesystemForModuleDependency(
|
||||
|
||||
ModuleDependencyVector
|
||||
ModuleDependencyScanningWorker::scanFilesystemForSwiftModuleDependency(
|
||||
StringRef moduleName, const ModuleDependenciesCache &cache) {
|
||||
Identifier moduleName, const ModuleDependenciesCache &cache) {
|
||||
return swiftScannerModuleLoader->getModuleDependencies(
|
||||
moduleName, cache.getModuleOutputPath(),
|
||||
cache.getScanService().getCachingFS(), cache.getAlreadySeenClangModules(),
|
||||
@@ -213,7 +213,7 @@ ModuleDependencyScanningWorker::scanFilesystemForSwiftModuleDependency(
|
||||
|
||||
ModuleDependencyVector
|
||||
ModuleDependencyScanningWorker::scanFilesystemForClangModuleDependency(
|
||||
StringRef moduleName, const ModuleDependenciesCache &cache) {
|
||||
Identifier moduleName, const ModuleDependenciesCache &cache) {
|
||||
return clangScannerModuleLoader->getModuleDependencies(
|
||||
moduleName, cache.getModuleOutputPath(),
|
||||
cache.getScanService().getCachingFS(), cache.getAlreadySeenClangModules(),
|
||||
@@ -252,6 +252,10 @@ auto ModuleDependencyScanner::withDependencyScanningWorker(Function &&F,
|
||||
return result;
|
||||
}
|
||||
|
||||
Identifier ModuleDependencyScanner::getModuleImportIdentifier(StringRef moduleName) {
|
||||
return ScanASTContext.getIdentifier(moduleName);
|
||||
}
|
||||
|
||||
ModuleDependencyScanner::ModuleDependencyScanner(
|
||||
SwiftDependencyScanningService &ScanningService,
|
||||
const CompilerInvocation &ScanCompilerInvocation,
|
||||
@@ -443,10 +447,11 @@ ModuleDependencyScanner::getNamedClangModuleDependencyInfo(
|
||||
return found;
|
||||
|
||||
// Otherwise perform filesystem scan
|
||||
auto moduleIdentifier = getModuleImportIdentifier(moduleName);
|
||||
auto moduleDependencies = withDependencyScanningWorker(
|
||||
[&cache, moduleName](ModuleDependencyScanningWorker *ScanningWorker) {
|
||||
[&cache, moduleIdentifier](ModuleDependencyScanningWorker *ScanningWorker) {
|
||||
return ScanningWorker->scanFilesystemForClangModuleDependency(
|
||||
moduleName, cache);
|
||||
moduleIdentifier, cache);
|
||||
});
|
||||
if (moduleDependencies.empty())
|
||||
return llvm::None;
|
||||
@@ -474,10 +479,11 @@ ModuleDependencyScanner::getNamedSwiftModuleDependencyInfo(
|
||||
return found;
|
||||
|
||||
// Otherwise perform filesystem scan
|
||||
auto moduleIdentifier = getModuleImportIdentifier(moduleName);
|
||||
auto moduleDependencies = withDependencyScanningWorker(
|
||||
[&cache, moduleName](ModuleDependencyScanningWorker *ScanningWorker) {
|
||||
[&cache, moduleIdentifier](ModuleDependencyScanningWorker *ScanningWorker) {
|
||||
return ScanningWorker->scanFilesystemForSwiftModuleDependency(
|
||||
moduleName, cache);
|
||||
moduleIdentifier, cache);
|
||||
});
|
||||
if (moduleDependencies.empty())
|
||||
return llvm::None;
|
||||
@@ -552,8 +558,9 @@ void ModuleDependencyScanner::resolveImportDependencies(
|
||||
// A scanning task to query a module by-name. If the module already exists
|
||||
// in the cache, do nothing and return.
|
||||
auto scanForModuleDependency = [this, &cache, &moduleLookupResult](
|
||||
StringRef moduleName, bool onlyClangModule,
|
||||
Identifier moduleIdentifier, bool onlyClangModule,
|
||||
bool isTestable) {
|
||||
auto moduleName = moduleIdentifier.str();
|
||||
// If this is already in the cache, no work to do here
|
||||
if (onlyClangModule) {
|
||||
if (cache.hasDependency(moduleName, ModuleDependencyKind::Clang))
|
||||
@@ -564,13 +571,13 @@ void ModuleDependencyScanner::resolveImportDependencies(
|
||||
}
|
||||
|
||||
auto moduleDependencies = withDependencyScanningWorker(
|
||||
[&cache, moduleName, onlyClangModule,
|
||||
[&cache, moduleIdentifier, onlyClangModule,
|
||||
isTestable](ModuleDependencyScanningWorker *ScanningWorker) {
|
||||
return onlyClangModule
|
||||
? ScanningWorker->scanFilesystemForClangModuleDependency(
|
||||
moduleName, cache)
|
||||
moduleIdentifier, cache)
|
||||
: ScanningWorker->scanFilesystemForModuleDependency(
|
||||
moduleName, cache, isTestable);
|
||||
moduleIdentifier, cache, isTestable);
|
||||
});
|
||||
moduleLookupResult.insert_or_assign(moduleName, moduleDependencies);
|
||||
};
|
||||
@@ -579,14 +586,14 @@ void ModuleDependencyScanner::resolveImportDependencies(
|
||||
for (const auto &dependsOn : moduleDependencyInfo->getModuleImports()) {
|
||||
bool underlyingClangModuleLookup = moduleID.ModuleName == dependsOn;
|
||||
bool isTestable = moduleDependencyInfo->isTestableImport(dependsOn);
|
||||
ScanningThreadPool.async(scanForModuleDependency, dependsOn,
|
||||
ScanningThreadPool.async(scanForModuleDependency, getModuleImportIdentifier(dependsOn),
|
||||
underlyingClangModuleLookup, isTestable);
|
||||
}
|
||||
for (const auto &dependsOn :
|
||||
moduleDependencyInfo->getOptionalModuleImports()) {
|
||||
bool underlyingClangModuleLookup = moduleID.ModuleName == dependsOn;
|
||||
bool isTestable = moduleDependencyInfo->isTestableImport(dependsOn);
|
||||
ScanningThreadPool.async(scanForModuleDependency, dependsOn,
|
||||
ScanningThreadPool.async(scanForModuleDependency, getModuleImportIdentifier(dependsOn),
|
||||
underlyingClangModuleLookup, isTestable);
|
||||
}
|
||||
ScanningThreadPool.wait();
|
||||
@@ -726,15 +733,16 @@ void ModuleDependencyScanner::resolveSwiftOverlayDependencies(
|
||||
// A scanning task to query a Swift module by-name. If the module already
|
||||
// exists in the cache, do nothing and return.
|
||||
auto scanForSwiftDependency = [this, &cache, &swiftOverlayLookupResult](
|
||||
StringRef moduleName) {
|
||||
Identifier moduleIdentifier) {
|
||||
auto moduleName = moduleIdentifier.str();
|
||||
if (cache.hasDependency(moduleName, ModuleDependencyKind::SwiftInterface) ||
|
||||
cache.hasDependency(moduleName, ModuleDependencyKind::SwiftBinary) ||
|
||||
cache.hasDependency(moduleName, ModuleDependencyKind::SwiftPlaceholder))
|
||||
return;
|
||||
|
||||
auto moduleDependencies = withDependencyScanningWorker(
|
||||
[&cache, moduleName](ModuleDependencyScanningWorker *ScanningWorker) {
|
||||
return ScanningWorker->scanFilesystemForSwiftModuleDependency(moduleName,
|
||||
[&cache, moduleIdentifier](ModuleDependencyScanningWorker *ScanningWorker) {
|
||||
return ScanningWorker->scanFilesystemForSwiftModuleDependency(moduleIdentifier,
|
||||
cache);
|
||||
});
|
||||
swiftOverlayLookupResult.insert_or_assign(moduleName, moduleDependencies);
|
||||
@@ -742,7 +750,7 @@ void ModuleDependencyScanner::resolveSwiftOverlayDependencies(
|
||||
|
||||
// Enque asynchronous lookup tasks
|
||||
for (const auto &clangDep : clangDependencies)
|
||||
ScanningThreadPool.async(scanForSwiftDependency, clangDep);
|
||||
ScanningThreadPool.async(scanForSwiftDependency, getModuleImportIdentifier(clangDep));
|
||||
ScanningThreadPool.wait();
|
||||
|
||||
// Aggregate both previously-cached and freshly-scanned module results
|
||||
|
||||
@@ -155,7 +155,7 @@ void SourceLoader::loadExtensions(NominalTypeDecl *nominal,
|
||||
}
|
||||
|
||||
ModuleDependencyVector
|
||||
SourceLoader::getModuleDependencies(StringRef moduleName,
|
||||
SourceLoader::getModuleDependencies(Identifier moduleName,
|
||||
StringRef moduleOutputPath,
|
||||
llvm::IntrusiveRefCntPtr<llvm::cas::CachingOnDiskFileSystem> CacheFS,
|
||||
const llvm::DenseSet<clang::tooling::dependencies::ModuleID> &alreadySeenClangModules,
|
||||
|
||||
@@ -305,14 +305,14 @@ SwiftModuleScanner::scanInterfaceFile(Twine moduleInterfacePath,
|
||||
}
|
||||
|
||||
ModuleDependencyVector SerializedModuleLoaderBase::getModuleDependencies(
|
||||
StringRef moduleName, StringRef moduleOutputPath,
|
||||
Identifier moduleName, StringRef moduleOutputPath,
|
||||
llvm::IntrusiveRefCntPtr<llvm::cas::CachingOnDiskFileSystem> CacheFS,
|
||||
const llvm::DenseSet<clang::tooling::dependencies::ModuleID>
|
||||
&alreadySeenClangModules,
|
||||
clang::tooling::dependencies::DependencyScanningTool &clangScanningTool,
|
||||
InterfaceSubContextDelegate &delegate, llvm::TreePathPrefixMapper *mapper,
|
||||
bool isTestableDependencyLookup) {
|
||||
ImportPath::Module::Builder builder(Ctx, moduleName, /*separator=*/'.');
|
||||
ImportPath::Module::Builder builder(moduleName);
|
||||
auto modulePath = builder.get();
|
||||
auto moduleId = modulePath.front().Item;
|
||||
llvm::Optional<SwiftDependencyTracker> tracker = llvm::None;
|
||||
@@ -344,7 +344,7 @@ ModuleDependencyVector SerializedModuleLoaderBase::getModuleDependencies(
|
||||
|
||||
ModuleDependencyVector moduleDependnecies;
|
||||
moduleDependnecies.push_back(
|
||||
std::make_pair(ModuleDependencyID{moduleName.str(),
|
||||
std::make_pair(ModuleDependencyID{moduleName.str().str(),
|
||||
scanner->dependencies->getKind()},
|
||||
*(scanner->dependencies)));
|
||||
return moduleDependnecies;
|
||||
|
||||
Reference in New Issue
Block a user