Skip to content

Commit ad7dbc5

Browse files
authored
Merge pull request #38703 from artemcm/DepScanCacheSearchPathDisambiguate
[Dependency Scanning] Have the scanner cache answer queries relevant to current search paths only.
2 parents 21405d8 + 6a12dc0 commit ad7dbc5

File tree

11 files changed

+479
-140
lines changed

11 files changed

+479
-140
lines changed

include/swift/AST/ASTContext.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include "llvm/ADT/PointerIntPair.h"
3838
#include "llvm/ADT/SetVector.h"
3939
#include "llvm/ADT/SmallPtrSet.h"
40+
#include "llvm/ADT/StringSet.h"
4041
#include "llvm/ADT/StringMap.h"
4142
#include "llvm/ADT/TinyPtrVector.h"
4243
#include "llvm/Support/Allocator.h"
@@ -854,6 +855,13 @@ class ASTContext final {
854855
ModuleDependenciesCache &cache,
855856
InterfaceSubContextDelegate &delegate);
856857

858+
/// Compute the extra implicit framework search paths on Apple platforms:
859+
/// $SDKROOT/System/Library/Frameworks/ and $SDKROOT/Library/Frameworks/.
860+
std::vector<std::string> getDarwinImplicitFrameworkSearchPaths() const;
861+
862+
/// Return a set of all possible filesystem locations where modules can be found.
863+
llvm::StringSet<> getAllModuleSearchPathsSet() const;
864+
857865
/// Load extensions to the given nominal type from the external
858866
/// module loaders.
859867
///

include/swift/AST/ModuleDependencies.h

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,12 @@ enum class ModuleDependenciesKind : int8_t {
6363
Clang,
6464
};
6565

66+
/// Details of a given module used for dependency scanner cache queries.
67+
struct ModuleLookupSpecifics {
68+
Optional<ModuleDependenciesKind> kind;
69+
llvm::StringSet<> currentSearchPaths;
70+
};
71+
6672
/// Base class for the variant storage of ModuleDependencies.
6773
///
6874
/// This class is mostly an implementation detail for \c ModuleDependencies.
@@ -407,21 +413,25 @@ using ModuleDependencyID = std::pair<std::string, ModuleDependenciesKind>;
407413
/// A cache describing the set of module dependencies that has been queried
408414
/// thus far.
409415
class ModuleDependenciesCache {
416+
using ModuleDependenciesVector = llvm::SmallVector<ModuleDependencies, 1>;
417+
410418
/// All cached module dependencies, in the order in which they were
411419
/// encountered.
412420
std::vector<ModuleDependencyID> AllModules;
413421

414422
/// Dependencies for Textual Swift modules that have already been computed.
415-
llvm::StringMap<ModuleDependencies> SwiftTextualModuleDependencies;
423+
/// This maps a module's id (name, kind) to a vector of Dependency objects, which correspond
424+
/// to instances of the same module that may have been found in different sets of search paths.
425+
llvm::StringMap<ModuleDependenciesVector> SwiftTextualModuleDependencies;
416426

417427
/// Dependencies for Binary Swift modules that have already been computed.
418-
llvm::StringMap<ModuleDependencies> SwiftBinaryModuleDependencies;
428+
llvm::StringMap<ModuleDependenciesVector> SwiftBinaryModuleDependencies;
419429

420430
/// Dependencies for Swift placeholder dependency modules that have already been computed.
421-
llvm::StringMap<ModuleDependencies> SwiftPlaceholderModuleDependencies;
431+
llvm::StringMap<ModuleDependenciesVector> SwiftPlaceholderModuleDependencies;
422432

423433
/// Dependencies for Clang modules that have already been computed.
424-
llvm::StringMap<ModuleDependencies> ClangModuleDependencies;
434+
llvm::StringMap<ModuleDependenciesVector> ClangModuleDependencies;
425435

426436
/// Additional information needed for Clang dependency scanning.
427437
ClangModuleDependenciesCacheImpl *clangImpl = nullptr;
@@ -437,9 +447,9 @@ class ModuleDependenciesCache {
437447

438448
/// Retrieve the dependencies map that corresponds to the given dependency
439449
/// kind.
440-
llvm::StringMap<ModuleDependencies> &getDependenciesMap(
450+
llvm::StringMap<ModuleDependenciesVector> &getDependenciesMap(
441451
ModuleDependenciesKind kind);
442-
const llvm::StringMap<ModuleDependencies> &getDependenciesMap(
452+
const llvm::StringMap<ModuleDependenciesVector> &getDependenciesMap(
443453
ModuleDependenciesKind kind) const;
444454

445455
public:
@@ -469,12 +479,21 @@ class ModuleDependenciesCache {
469479

470480
/// Whether we have cached dependency information for the given module.
471481
bool hasDependencies(StringRef moduleName,
472-
Optional<ModuleDependenciesKind> kind) const;
482+
ModuleLookupSpecifics details) const;
473483

474-
/// Look for module dependencies for a module with the given name.
484+
/// Look for module dependencies for a module with the given name given current search paths.
475485
///
476486
/// \returns the cached result, or \c None if there is no cached entry.
477487
Optional<ModuleDependencies> findDependencies(
488+
StringRef moduleName,
489+
ModuleLookupSpecifics details) const;
490+
491+
/// Look for module dependencies for a module with the given name.
492+
/// This method has a deliberately-obtuse name to indicate that it is not to be used for general
493+
/// queries.
494+
///
495+
/// \returns the cached result, or \c None if there is no cached entry.
496+
Optional<ModuleDependenciesVector> findAllDependenciesIrrespectiveOfSearchPaths(
478497
StringRef moduleName,
479498
Optional<ModuleDependenciesKind> kind) const;
480499

lib/AST/ASTContext.cpp

Lines changed: 73 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#include "swift/AST/PropertyWrappers.h"
4242
#include "swift/AST/ProtocolConformance.h"
4343
#include "swift/AST/RawComment.h"
44+
#include "swift/AST/SearchPathOptions.h"
4445
#include "swift/AST/SILLayout.h"
4546
#include "swift/AST/SemanticAttrs.h"
4647
#include "swift/AST/SourceFile.h"
@@ -1645,29 +1646,32 @@ Optional<ModuleDependencies> ASTContext::getModuleDependencies(
16451646
bool cacheOnly) {
16461647
// Retrieve the dependencies for this module.
16471648
if (cacheOnly) {
1649+
auto searchPathSet = getAllModuleSearchPathsSet();
16481650
// Check whether we've cached this result.
16491651
if (!isUnderlyingClangModule) {
1650-
if (auto found = cache.findDependencies(moduleName,
1651-
ModuleDependenciesKind::SwiftTextual))
1652+
if (auto found = cache.findDependencies(
1653+
moduleName,
1654+
{ModuleDependenciesKind::SwiftTextual, searchPathSet}))
16521655
return found;
1653-
if (auto found = cache.findDependencies(moduleName,
1654-
ModuleDependenciesKind::SwiftTextual))
1656+
if (auto found = cache.findDependencies(
1657+
moduleName, {ModuleDependenciesKind::SwiftBinary, searchPathSet}))
16551658
return found;
1656-
if (auto found = cache.findDependencies(moduleName,
1657-
ModuleDependenciesKind::SwiftPlaceholder))
1659+
if (auto found = cache.findDependencies(
1660+
moduleName,
1661+
{ModuleDependenciesKind::SwiftPlaceholder, searchPathSet}))
16581662
return found;
16591663
}
1660-
if (auto found = cache.findDependencies(moduleName,
1661-
ModuleDependenciesKind::Clang))
1664+
if (auto found = cache.findDependencies(
1665+
moduleName, {ModuleDependenciesKind::Clang, searchPathSet}))
16621666
return found;
16631667
} else {
16641668
for (auto &loader : getImpl().ModuleLoaders) {
16651669
if (isUnderlyingClangModule &&
16661670
loader.get() != getImpl().TheClangModuleLoader)
16671671
continue;
16681672

1669-
if (auto dependencies = loader->getModuleDependencies(moduleName, cache,
1670-
delegate))
1673+
if (auto dependencies =
1674+
loader->getModuleDependencies(moduleName, cache, delegate))
16711675
return dependencies;
16721676
}
16731677
}
@@ -1690,6 +1694,65 @@ ASTContext::getSwiftModuleDependencies(StringRef moduleName,
16901694
return None;
16911695
}
16921696

1697+
namespace {
1698+
static StringRef
1699+
pathStringFromFrameworkSearchPath(const SearchPathOptions::FrameworkSearchPath &next) {
1700+
return next.Path;
1701+
};
1702+
}
1703+
1704+
std::vector<std::string> ASTContext::getDarwinImplicitFrameworkSearchPaths()
1705+
const {
1706+
assert(LangOpts.Target.isOSDarwin());
1707+
SmallString<128> systemFrameworksScratch;
1708+
systemFrameworksScratch = SearchPathOpts.SDKPath;
1709+
llvm::sys::path::append(systemFrameworksScratch, "System", "Library", "Frameworks");
1710+
1711+
SmallString<128> frameworksScratch;
1712+
frameworksScratch = SearchPathOpts.SDKPath;
1713+
llvm::sys::path::append(frameworksScratch, "Library", "Frameworks");
1714+
return {systemFrameworksScratch.str().str(), frameworksScratch.str().str()};
1715+
}
1716+
1717+
llvm::StringSet<> ASTContext::getAllModuleSearchPathsSet()
1718+
const {
1719+
llvm::StringSet<> result;
1720+
result.insert(SearchPathOpts.ImportSearchPaths.begin(),
1721+
SearchPathOpts.ImportSearchPaths.end());
1722+
1723+
// Framework paths are "special", they contain more than path strings,
1724+
// but path strings are all we care about here.
1725+
using FrameworkPathView = ArrayRefView<SearchPathOptions::FrameworkSearchPath,
1726+
StringRef,
1727+
pathStringFromFrameworkSearchPath>;
1728+
FrameworkPathView frameworkPathsOnly{SearchPathOpts.FrameworkSearchPaths};
1729+
result.insert(frameworkPathsOnly.begin(), frameworkPathsOnly.end());
1730+
1731+
if (LangOpts.Target.isOSDarwin()) {
1732+
auto implicitFrameworkSearchPaths = getDarwinImplicitFrameworkSearchPaths();
1733+
result.insert(implicitFrameworkSearchPaths.begin(),
1734+
implicitFrameworkSearchPaths.end());
1735+
}
1736+
result.insert(SearchPathOpts.RuntimeLibraryImportPaths.begin(),
1737+
SearchPathOpts.RuntimeLibraryImportPaths.end());
1738+
1739+
// ClangImporter special-cases the path for SwiftShims, so do the same here
1740+
// If there are no shims in the resource dir, add a search path in the SDK.
1741+
SmallString<128> shimsPath(SearchPathOpts.RuntimeResourcePath);
1742+
llvm::sys::path::append(shimsPath, "shims");
1743+
if (!llvm::sys::fs::exists(shimsPath)) {
1744+
shimsPath = SearchPathOpts.SDKPath;
1745+
llvm::sys::path::append(shimsPath, "usr", "lib", "swift", "shims");
1746+
}
1747+
result.insert(shimsPath.str());
1748+
1749+
// Clang system modules are found in the SDK root
1750+
SmallString<128> clangSysRootPath(SearchPathOpts.SDKPath);
1751+
llvm::sys::path::append(clangSysRootPath, "usr", "include");
1752+
result.insert(clangSysRootPath.str());
1753+
return result;
1754+
}
1755+
16931756
void ASTContext::loadExtensions(NominalTypeDecl *nominal,
16941757
unsigned previousGeneration) {
16951758
PrettyStackTraceDecl stackTrace("loading extensions for", nominal);

0 commit comments

Comments
 (0)