@@ -182,3 +182,70 @@ export *\n\
182
182
183
183
swiftscan_dependency_graph_dispose (Dependencies);
184
184
}
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