Include system-ness of framework and import search paths in the PCH hash

This hash is also used for the dependency scanning hash. In both cases, PCH contents may differ based on whether a certain module they depend on is found in a system or non-system search path. In dependency scanning, systemness should cause a full change of scanning context requiring a from-scratch scan.

Resolves rdar://150334077
This commit is contained in:
Artem Chikin
2025-05-01 16:21:59 -07:00
parent 28289e9d94
commit b684af4c88
5 changed files with 25 additions and 60 deletions

View File

@@ -1094,9 +1094,6 @@ public:
/// $SDKROOT/System/Library/Frameworks/ and $SDKROOT/Library/Frameworks/. /// $SDKROOT/System/Library/Frameworks/ and $SDKROOT/Library/Frameworks/.
std::vector<std::string> getDarwinImplicitFrameworkSearchPaths() const; std::vector<std::string> getDarwinImplicitFrameworkSearchPaths() const;
/// Return a set of all possible filesystem locations where modules can be found.
llvm::StringSet<> getAllModuleSearchPathsSet() const;
/// Load extensions to the given nominal type from the external /// Load extensions to the given nominal type from the external
/// module loaders. /// module loaders.
/// ///

View File

@@ -323,6 +323,10 @@ public:
friend bool operator!=(const SearchPath &LHS, const SearchPath &RHS) { friend bool operator!=(const SearchPath &LHS, const SearchPath &RHS) {
return !(LHS == RHS); return !(LHS == RHS);
} }
friend llvm::hash_code
hash_value(const SearchPath &searchPath) {
return llvm::hash_combine(searchPath.Path, searchPath.IsSystem);
}
}; };
private: private:
@@ -599,30 +603,17 @@ public:
makeOverlayFileSystem( makeOverlayFileSystem(
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS) const; llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS) const;
private:
static StringRef pathStringFromSearchPath(const SearchPath &next) {
return next.Path;
};
public: public:
/// Return a hash code of any components from these options that should /// Return a hash code of any components from these options that should
/// contribute to a Swift Bridging PCH hash. /// contribute to a Swift Bridging PCH hash.
llvm::hash_code getPCHHashComponents() const { llvm::hash_code getPCHHashComponents() const {
using llvm::hash_combine; using llvm::hash_combine;
using llvm::hash_combine_range; using llvm::hash_combine_range;
using SearchPathView =
ArrayRefView<SearchPath, StringRef, pathStringFromSearchPath>;
SearchPathView importPathsOnly{ImportSearchPaths};
SearchPathView frameworkPathsOnly{FrameworkSearchPaths};
return hash_combine(SDKPath, return hash_combine(SDKPath,
// FIXME: Should we include the system-ness of hash_combine_range(ImportSearchPaths.begin(), ImportSearchPaths.end()),
// search paths too?
hash_combine_range(importPathsOnly.begin(), importPathsOnly.end()),
hash_combine_range(VFSOverlayFiles.begin(), VFSOverlayFiles.end()), hash_combine_range(VFSOverlayFiles.begin(), VFSOverlayFiles.end()),
hash_combine_range(frameworkPathsOnly.begin(), hash_combine_range(FrameworkSearchPaths.begin(),
frameworkPathsOnly.end()), FrameworkSearchPaths.end()),
hash_combine_range(LibrarySearchPaths.begin(), hash_combine_range(LibrarySearchPaths.begin(),
LibrarySearchPaths.end()), LibrarySearchPaths.end()),
RuntimeResourcePath, RuntimeResourcePath,

View File

@@ -41,7 +41,7 @@ using llvm::BCVBR;
const unsigned char MODULE_DEPENDENCY_CACHE_FORMAT_SIGNATURE[] = {'I', 'M', 'D','C'}; const unsigned char MODULE_DEPENDENCY_CACHE_FORMAT_SIGNATURE[] = {'I', 'M', 'D','C'};
const unsigned MODULE_DEPENDENCY_CACHE_FORMAT_VERSION_MAJOR = 9; const unsigned MODULE_DEPENDENCY_CACHE_FORMAT_VERSION_MAJOR = 9;
/// Increment this on every change. /// Increment this on every change.
const unsigned MODULE_DEPENDENCY_CACHE_FORMAT_VERSION_MINOR = 1; const unsigned MODULE_DEPENDENCY_CACHE_FORMAT_VERSION_MINOR = 2;
/// Various identifiers in this format will rely on having their strings mapped /// Various identifiers in this format will rely on having their strings mapped
/// using this ID. /// using this ID.

View File

@@ -2212,46 +2212,6 @@ const {
return SearchPathOpts.getDarwinImplicitFrameworkSearchPaths(); return SearchPathOpts.getDarwinImplicitFrameworkSearchPaths();
} }
llvm::StringSet<> ASTContext::getAllModuleSearchPathsSet()
const {
llvm::StringSet<> result;
// Import and framework paths are "special", they contain more than path
// strings, but path strings are all we care about here.
using SearchPathView = ArrayRefView<SearchPathOptions::SearchPath, StringRef,
pathStringFromSearchPath>;
SearchPathView importPathsOnly{SearchPathOpts.getImportSearchPaths()};
result.insert(importPathsOnly.begin(), importPathsOnly.end());
SearchPathView frameworkPathsOnly{SearchPathOpts.getFrameworkSearchPaths()};
result.insert(frameworkPathsOnly.begin(), frameworkPathsOnly.end());
if (LangOpts.Target.isOSDarwin()) {
auto implicitFrameworkSearchPaths = getDarwinImplicitFrameworkSearchPaths();
result.insert(implicitFrameworkSearchPaths.begin(),
implicitFrameworkSearchPaths.end());
}
result.insert(SearchPathOpts.RuntimeLibraryImportPaths.begin(),
SearchPathOpts.RuntimeLibraryImportPaths.end());
// ClangImporter special-cases the path for SwiftShims, so do the same here
// If there are no shims in the resource dir, add a search path in the SDK.
SmallString<128> shimsPath(SearchPathOpts.RuntimeResourcePath);
llvm::sys::path::append(shimsPath, "shims");
if (!llvm::sys::fs::exists(shimsPath)) {
shimsPath = SearchPathOpts.getSDKPath();
llvm::sys::path::append(shimsPath, "usr", "lib", "swift", "shims");
}
result.insert(shimsPath.str());
// Clang system modules are found in the SDK root
SmallString<128> clangSysRootPath(SearchPathOpts.getSDKPath());
llvm::sys::path::append(clangSysRootPath, "usr", "include");
result.insert(clangSysRootPath.str());
return result;
}
void ASTContext::loadExtensions(NominalTypeDecl *nominal, void ASTContext::loadExtensions(NominalTypeDecl *nominal,
unsigned previousGeneration) { unsigned previousGeneration) {
PrettyStackTraceDecl stackTrace("loading extensions for", nominal); PrettyStackTraceDecl stackTrace("loading extensions for", nominal);

View File

@@ -0,0 +1,17 @@
// RUN: %empty-directory(%t)
// RUN: %empty-directory(%t/module-cache)
// RUN: %empty-directory(%t/Frameworks)
// RUN: %target-swift-frontend -scan-dependencies -scanner-module-validation -module-load-mode prefer-interface -Rdependency-scan-cache -load-dependency-scan-cache -serialize-dependency-scan-cache -dependency-scan-cache-path %t/cache.moddepcache -module-cache-path %t/module-cache %s -o %t/deps.json -I %t/ExtraCModules -I %S/../Inputs/CHeaders -F %t/Frameworks &> %t/first_scan_output.txt
// RUN: cat %t/first_scan_output.txt | %FileCheck %s
// RUN: %target-swift-frontend -scan-dependencies -scanner-module-validation -module-load-mode prefer-interface -Rdependency-scan-cache -load-dependency-scan-cache -serialize-dependency-scan-cache -dependency-scan-cache-path %t/cache.moddepcache -module-cache-path %t/module-cache %s -o %t/deps.json -I %t/ExtraCModules -I %S/../Inputs/CHeaders -F %t/Frameworks &> %t/second_scan_output.txt
// RUN: cat %t/second_scan_output.txt | %FileCheck %s -check-prefix=INCREMENTAL-CHECK
// Change an '-F' to a '-Fsystem' and ensure that the serialized cache does not get reused
// RUN: %target-swift-frontend -scan-dependencies -scanner-module-validation -module-load-mode prefer-interface -Rdependency-scan-cache -load-dependency-scan-cache -serialize-dependency-scan-cache -dependency-scan-cache-path %t/cache.moddepcache -module-cache-path %t/module-cache %s -o %t/deps.json -I %t/ExtraCModules -I %S/../Inputs/CHeaders -Fsystem %t/Frameworks &> %t/second_system_scan_output.txt
// RUN: cat %t/second_system_scan_output.txt | %FileCheck %s
// CHECK: remark: Incremental module scan: Failed to load module scanning dependency cache from:
// INCREMENTAL-CHECK-NOT: remark: Incremental module scan: Failed to load module scanning dependency cache from: