diff --git a/lib/ClangImporter/ClangModuleDependencyScanner.cpp b/lib/ClangImporter/ClangModuleDependencyScanner.cpp index 3c478972e4974..e48f784ea9bc4 100644 --- a/lib/ClangImporter/ClangModuleDependencyScanner.cpp +++ b/lib/ClangImporter/ClangModuleDependencyScanner.cpp @@ -28,11 +28,11 @@ using namespace clang::tooling; using namespace clang::tooling::dependencies; class swift::ClangModuleDependenciesCacheImpl { - /// The name of the file used for the "import hack" to compute module + /// Cache the names of the files used for the "import hack" to compute module /// dependencies. /// FIXME: This should go away once Clang's dependency scanning library /// can scan by module name. - std::string importHackFile; + llvm::StringMap importHackFileCache; public: /// Set containing all of the Clang modules that have already been seen. @@ -43,38 +43,41 @@ class swift::ClangModuleDependenciesCacheImpl { DependencyScanningTool tool; ClangModuleDependenciesCacheImpl() - : service(ScanningMode::MinimizedSourcePreprocessing, - ScanningOutputFormat::Full), + : importHackFileCache(), + service(ScanningMode::MinimizedSourcePreprocessing, ScanningOutputFormat::Full), tool(service) { } ~ClangModuleDependenciesCacheImpl(); /// Retrieve the name of the file used for the "import hack" that is /// used to scan the dependencies of a Clang module. - llvm::ErrorOr getImportHackFile(); + llvm::ErrorOr getImportHackFile(StringRef moduleName); }; ClangModuleDependenciesCacheImpl::~ClangModuleDependenciesCacheImpl() { - if (!importHackFile.empty()) { - llvm::sys::fs::remove(importHackFile); + if (!importHackFileCache.empty()) { + for (auto& it: importHackFileCache) { + llvm::sys::fs::remove(it.second); + } } } -llvm::ErrorOr ClangModuleDependenciesCacheImpl::getImportHackFile() { - if (!importHackFile.empty()) - return importHackFile; +llvm::ErrorOr ClangModuleDependenciesCacheImpl::getImportHackFile(StringRef moduleName) { + auto cacheIt = importHackFileCache.find(moduleName.str()); + if (cacheIt != importHackFileCache.end()) + return cacheIt->second; // Create a temporary file. int resultFD; SmallString<128> resultPath; if (auto error = llvm::sys::fs::createTemporaryFile( - "import-hack", "m", resultFD, resultPath)) + "import-hack-" + moduleName.str(), "c", resultFD, resultPath)) return error; llvm::raw_fd_ostream out(resultFD, /*shouldClose=*/true); - out << "@import HACK_MODULE_NAME;\n"; + out << "#pragma clang module import " << moduleName.str() << ";\n"; llvm::sys::RemoveFileOnSignal(resultPath); - importHackFile = resultPath.str().str(); - return importHackFile; + importHackFileCache.insert(std::make_pair(moduleName, resultPath.str().str())); + return importHackFileCache[moduleName]; } namespace { @@ -283,12 +286,11 @@ Optional ClangImporter::getModuleDependencies( auto clangImpl = getOrCreateClangImpl(cache); // HACK! Replace the module import buffer name with the source file hack. - auto importHackFile = clangImpl->getImportHackFile(); + auto importHackFile = clangImpl->getImportHackFile(moduleName); if (!importHackFile) { // FIXME: Emit a diagnostic here. return None; } - // Reform the Clang importer options. // FIXME: Just save a reference or copy so we can get this back. ClangImporterOptions importerOpts; @@ -299,12 +301,6 @@ Optional ClangImporter::getModuleDependencies( getClangDepScanningInvocationArguments( ctx, importerOpts, *importHackFile); - // HACK! Trick out a .m file to use to import the module we name. - std::string moduleNameHackDefine = - ("-DHACK_MODULE_NAME=" + moduleName).str(); - commandLineArgs.push_back(moduleNameHackDefine); - commandLineArgs.push_back("-fmodules-ignore-macro=HACK_MODULE_NAME"); - std::string workingDir = ctx.SourceMgr.getFileSystem()->getCurrentWorkingDirectory().get(); CompileCommand command(workingDir, *importHackFile, commandLineArgs, "-"); @@ -312,7 +308,6 @@ Optional ClangImporter::getModuleDependencies( auto clangDependencies = clangImpl->tool.getFullDependencies( database, workingDir, clangImpl->alreadySeen); - if (!clangDependencies) { // FIXME: Route this to a normal diagnostic. llvm::logAllUnhandledErrors(clangDependencies.takeError(), llvm::errs()); @@ -321,7 +316,6 @@ Optional ClangImporter::getModuleDependencies( // Record module dependencies for each module we found. recordModuleDependencies(cache, *clangDependencies); - return cache.findDependencies(moduleName, ModuleDependenciesKind::Clang); }