Skip to content

Commit 4dee668

Browse files
authored
Merge pull request #65415 from artemcm/StricterDepScanHashWithFrontendOpts
[Dependency Scanning] Consider scanned module name a part of the scanning context (hash)
2 parents 400bfc6 + 60806ef commit 4dee668

File tree

3 files changed

+78
-6
lines changed

3 files changed

+78
-6
lines changed

include/swift/DependencyScan/DependencyScanningTool.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -96,17 +96,17 @@ class DependencyScanningTool {
9696
/// Discared the collection of diagnostics encountered so far.
9797
void resetDiagnostics();
9898

99+
/// Using the specified invocation command, instantiate a CompilerInstance
100+
/// that will be used for this scan.
101+
llvm::ErrorOr<std::unique_ptr<CompilerInstance>>
102+
initCompilerInstanceForScan(ArrayRef<const char *> Command);
103+
99104
private:
100105
/// Using the specified invocation command, initialize the scanner instance
101106
/// for this scan. Returns the `CompilerInstance` that will be used.
102107
llvm::ErrorOr<std::unique_ptr<CompilerInstance>>
103108
initScannerForAction(ArrayRef<const char *> Command);
104109

105-
/// Using the specified invocation command, instantiate a CompilerInstance
106-
/// that will be used for this scan.
107-
llvm::ErrorOr<std::unique_ptr<CompilerInstance>>
108-
initCompilerInstanceForScan(ArrayRef<const char *> Command);
109-
110110
/// Shared cache of module dependencies, re-used by individual full-scan queries
111111
/// during the lifetime of this Tool.
112112
std::unique_ptr<SwiftDependencyScanningService> ScanningService;

include/swift/Frontend/FrontendOptions.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,12 @@ class FrontendOptions {
457457
/// Return a hash code of any components from these options that should
458458
/// contribute to a Swift Dependency Scanning hash.
459459
llvm::hash_code getModuleScanningHashComponents() const {
460-
return llvm::hash_value(0);
460+
return hash_combine(ModuleName,
461+
ModuleABIName,
462+
ModuleLinkName,
463+
ImplicitObjCHeaderPath,
464+
PrebuiltModuleCachePath,
465+
UserModuleVersion);
461466
}
462467

463468
StringRef determineFallbackModuleName() const;

unittests/DependencyScan/ModuleDeps.cpp

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,3 +182,70 @@ export *\n\
182182

183183
swiftscan_dependency_graph_dispose(Dependencies);
184184
}
185+
186+
TEST_F(ScanTest, TestModuleDepsHash) {
187+
SmallString<256> tempDir;
188+
ASSERT_FALSE(llvm::sys::fs::createUniqueDirectory("ScanTest.TestModuleDepsHash", tempDir));
189+
SWIFT_DEFER { llvm::sys::fs::remove_directories(tempDir); };
190+
191+
// Create test input file
192+
std::string TestPathStr = createFilename(tempDir, "foo.swift");
193+
ASSERT_FALSE(emitFileWithContents(tempDir, "foo.swift", "import A\n"));
194+
195+
// Create includes
196+
std::string IncludeDirPath = createFilename(tempDir, "include");
197+
ASSERT_FALSE(llvm::sys::fs::create_directory(IncludeDirPath));
198+
std::string SwiftDirPath = createFilename(IncludeDirPath, "Swift");
199+
ASSERT_FALSE(llvm::sys::fs::create_directory(SwiftDirPath));
200+
201+
// Create imported module Swift interface files
202+
ASSERT_FALSE(emitFileWithContents(SwiftDirPath, "A.swiftinterface",
203+
"// swift-interface-format-version: 1.0\n\
204+
// swift-module-flags: -module-name A\n\
205+
import Swift\n\
206+
public func overlayFuncA() { }\n"));
207+
208+
// Paths to shims and stdlib
209+
llvm::SmallString<128> ShimsLibDir = StdLibDir;
210+
llvm::sys::path::append(ShimsLibDir, "shims");
211+
auto Target = llvm::Triple(llvm::sys::getDefaultTargetTriple());
212+
llvm::sys::path::append(StdLibDir, getPlatformNameForTriple(Target));
213+
214+
std::vector<std::string> BaseCommandStrArr = {
215+
TestPathStr,
216+
std::string("-I ") + SwiftDirPath,
217+
std::string("-I ") + StdLibDir.str().str(),
218+
std::string("-I ") + ShimsLibDir.str().str(),
219+
};
220+
221+
std::vector<std::string> CommandStrArrA = BaseCommandStrArr;
222+
CommandStrArrA.push_back("-module-name");
223+
CommandStrArrA.push_back("A");
224+
std::vector<std::string> CommandStrArrB = BaseCommandStrArr;
225+
CommandStrArrB.push_back("-module-name");
226+
CommandStrArrB.push_back("B");
227+
228+
// On Windows we need to add an extra escape for path separator characters because otherwise
229+
// the command line tokenizer will treat them as escape characters.
230+
for (size_t i = 0; i < CommandStrArrA.size(); ++i) {
231+
std::replace(CommandStrArrA[i].begin(), CommandStrArrA[i].end(), '\\', '/');
232+
}
233+
std::vector<const char*> CommandA;
234+
for (auto &command : CommandStrArrA) {
235+
CommandA.push_back(command.c_str());
236+
}
237+
238+
for (size_t i = 0; i < CommandStrArrB.size(); ++i) {
239+
std::replace(CommandStrArrB[i].begin(), CommandStrArrB[i].end(), '\\', '/');
240+
}
241+
std::vector<const char*> CommandB;
242+
for (auto &command : CommandStrArrB) {
243+
CommandB.push_back(command.c_str());
244+
}
245+
246+
auto instanceA = ScannerTool.initCompilerInstanceForScan(CommandA);
247+
auto instanceB = ScannerTool.initCompilerInstanceForScan(CommandB);
248+
// Ensure that scans that only differ in module name have distinct scanning context hashes
249+
ASSERT_NE(instanceA->get()->getInvocation().getModuleScanningHash(),
250+
instanceB->get()->getInvocation().getModuleScanningHash());
251+
}

0 commit comments

Comments
 (0)