@@ -28,11 +28,11 @@ using namespace clang::tooling;
28
28
using namespace clang ::tooling::dependencies;
29
29
30
30
class swift ::ClangModuleDependenciesCacheImpl {
31
- // / The name of the file used for the "import hack" to compute module
31
+ // / Cache the names of the files used for the "import hack" to compute module
32
32
// / dependencies.
33
33
// / FIXME: This should go away once Clang's dependency scanning library
34
34
// / can scan by module name.
35
- std::string importHackFile ;
35
+ llvm::StringMap< std::string> importHackFileCache ;
36
36
37
37
public:
38
38
// / Set containing all of the Clang modules that have already been seen.
@@ -43,38 +43,41 @@ class swift::ClangModuleDependenciesCacheImpl {
43
43
DependencyScanningTool tool;
44
44
45
45
ClangModuleDependenciesCacheImpl ()
46
- : service(ScanningMode::MinimizedSourcePreprocessing ,
47
- ScanningOutputFormat::Full),
46
+ : importHackFileCache() ,
47
+ service (ScanningMode::MinimizedSourcePreprocessing, ScanningOutputFormat::Full),
48
48
tool(service) { }
49
49
~ClangModuleDependenciesCacheImpl ();
50
50
51
51
// / Retrieve the name of the file used for the "import hack" that is
52
52
// / used to scan the dependencies of a Clang module.
53
- llvm::ErrorOr<StringRef> getImportHackFile ();
53
+ llvm::ErrorOr<StringRef> getImportHackFile (StringRef moduleName );
54
54
};
55
55
56
56
ClangModuleDependenciesCacheImpl::~ClangModuleDependenciesCacheImpl () {
57
- if (!importHackFile.empty ()) {
58
- llvm::sys::fs::remove (importHackFile);
57
+ if (!importHackFileCache.empty ()) {
58
+ for (auto & it: importHackFileCache) {
59
+ llvm::sys::fs::remove (it.second );
60
+ }
59
61
}
60
62
}
61
63
62
- llvm::ErrorOr<StringRef> ClangModuleDependenciesCacheImpl::getImportHackFile () {
63
- if (!importHackFile.empty ())
64
- return importHackFile;
64
+ llvm::ErrorOr<StringRef> ClangModuleDependenciesCacheImpl::getImportHackFile (StringRef moduleName) {
65
+ auto cacheIt = importHackFileCache.find (moduleName.str ());
66
+ if (cacheIt != importHackFileCache.end ())
67
+ return cacheIt->second ;
65
68
66
69
// Create a temporary file.
67
70
int resultFD;
68
71
SmallString<128 > resultPath;
69
72
if (auto error = llvm::sys::fs::createTemporaryFile (
70
- " import-hack" , " m " , resultFD, resultPath))
73
+ " import-hack- " + moduleName. str () , " c " , resultFD, resultPath))
71
74
return error;
72
75
73
76
llvm::raw_fd_ostream out (resultFD, /* shouldClose=*/ true );
74
- out << " @ import HACK_MODULE_NAME ;\n " ;
77
+ out << " #pragma clang module import " << moduleName. str () << " ;\n " ;
75
78
llvm::sys::RemoveFileOnSignal (resultPath);
76
- importHackFile = resultPath.str ().str ();
77
- return importHackFile ;
79
+ importHackFileCache. insert ( std::make_pair (moduleName, resultPath.str ().str ()) );
80
+ return importHackFileCache[moduleName] ;
78
81
}
79
82
80
83
namespace {
@@ -283,12 +286,11 @@ Optional<ModuleDependencies> ClangImporter::getModuleDependencies(
283
286
auto clangImpl = getOrCreateClangImpl (cache);
284
287
285
288
// HACK! Replace the module import buffer name with the source file hack.
286
- auto importHackFile = clangImpl->getImportHackFile ();
289
+ auto importHackFile = clangImpl->getImportHackFile (moduleName );
287
290
if (!importHackFile) {
288
291
// FIXME: Emit a diagnostic here.
289
292
return None;
290
293
}
291
-
292
294
// Reform the Clang importer options.
293
295
// FIXME: Just save a reference or copy so we can get this back.
294
296
ClangImporterOptions importerOpts;
@@ -299,20 +301,13 @@ Optional<ModuleDependencies> ClangImporter::getModuleDependencies(
299
301
getClangDepScanningInvocationArguments (
300
302
ctx, importerOpts, *importHackFile);
301
303
302
- // HACK! Trick out a .m file to use to import the module we name.
303
- std::string moduleNameHackDefine =
304
- (" -DHACK_MODULE_NAME=" + moduleName).str ();
305
- commandLineArgs.push_back (moduleNameHackDefine);
306
- commandLineArgs.push_back (" -fmodules-ignore-macro=HACK_MODULE_NAME" );
307
-
308
304
std::string workingDir =
309
305
ctx.SourceMgr .getFileSystem ()->getCurrentWorkingDirectory ().get ();
310
306
CompileCommand command (workingDir, *importHackFile, commandLineArgs, " -" );
311
307
SingleCommandCompilationDatabase database (command);
312
308
313
309
auto clangDependencies = clangImpl->tool .getFullDependencies (
314
310
database, workingDir, clangImpl->alreadySeen );
315
-
316
311
if (!clangDependencies) {
317
312
// FIXME: Route this to a normal diagnostic.
318
313
llvm::logAllUnhandledErrors (clangDependencies.takeError (), llvm::errs ());
@@ -321,7 +316,6 @@ Optional<ModuleDependencies> ClangImporter::getModuleDependencies(
321
316
322
317
// Record module dependencies for each module we found.
323
318
recordModuleDependencies (cache, *clangDependencies);
324
-
325
319
return cache.findDependencies (moduleName, ModuleDependenciesKind::Clang);
326
320
}
327
321
0 commit comments