Skip to content

Commit 6bc0385

Browse files
authored
Merge pull request #32590 from artemcm/HackingWithCModules
[Dependency Scanner] Use `pragma clang module import` in the hack file used to invoke the clang dependency scanner.
2 parents 621b3b4 + 9ee4ebf commit 6bc0385

File tree

1 file changed

+18
-24
lines changed

1 file changed

+18
-24
lines changed

lib/ClangImporter/ClangModuleDependencyScanner.cpp

Lines changed: 18 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,11 @@ using namespace clang::tooling;
2828
using namespace clang::tooling::dependencies;
2929

3030
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
3232
/// dependencies.
3333
/// FIXME: This should go away once Clang's dependency scanning library
3434
/// can scan by module name.
35-
std::string importHackFile;
35+
llvm::StringMap<std::string> importHackFileCache;
3636

3737
public:
3838
/// Set containing all of the Clang modules that have already been seen.
@@ -43,38 +43,41 @@ class swift::ClangModuleDependenciesCacheImpl {
4343
DependencyScanningTool tool;
4444

4545
ClangModuleDependenciesCacheImpl()
46-
: service(ScanningMode::MinimizedSourcePreprocessing,
47-
ScanningOutputFormat::Full),
46+
: importHackFileCache(),
47+
service(ScanningMode::MinimizedSourcePreprocessing, ScanningOutputFormat::Full),
4848
tool(service) { }
4949
~ClangModuleDependenciesCacheImpl();
5050

5151
/// Retrieve the name of the file used for the "import hack" that is
5252
/// used to scan the dependencies of a Clang module.
53-
llvm::ErrorOr<StringRef> getImportHackFile();
53+
llvm::ErrorOr<StringRef> getImportHackFile(StringRef moduleName);
5454
};
5555

5656
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+
}
5961
}
6062
}
6163

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;
6568

6669
// Create a temporary file.
6770
int resultFD;
6871
SmallString<128> resultPath;
6972
if (auto error = llvm::sys::fs::createTemporaryFile(
70-
"import-hack", "m", resultFD, resultPath))
73+
"import-hack-" + moduleName.str(), "c", resultFD, resultPath))
7174
return error;
7275

7376
llvm::raw_fd_ostream out(resultFD, /*shouldClose=*/true);
74-
out << "@import HACK_MODULE_NAME;\n";
77+
out << "#pragma clang module import " << moduleName.str() << ";\n";
7578
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];
7881
}
7982

8083
namespace {
@@ -283,12 +286,11 @@ Optional<ModuleDependencies> ClangImporter::getModuleDependencies(
283286
auto clangImpl = getOrCreateClangImpl(cache);
284287

285288
// HACK! Replace the module import buffer name with the source file hack.
286-
auto importHackFile = clangImpl->getImportHackFile();
289+
auto importHackFile = clangImpl->getImportHackFile(moduleName);
287290
if (!importHackFile) {
288291
// FIXME: Emit a diagnostic here.
289292
return None;
290293
}
291-
292294
// Reform the Clang importer options.
293295
// FIXME: Just save a reference or copy so we can get this back.
294296
ClangImporterOptions importerOpts;
@@ -299,20 +301,13 @@ Optional<ModuleDependencies> ClangImporter::getModuleDependencies(
299301
getClangDepScanningInvocationArguments(
300302
ctx, importerOpts, *importHackFile);
301303

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-
308304
std::string workingDir =
309305
ctx.SourceMgr.getFileSystem()->getCurrentWorkingDirectory().get();
310306
CompileCommand command(workingDir, *importHackFile, commandLineArgs, "-");
311307
SingleCommandCompilationDatabase database(command);
312308

313309
auto clangDependencies = clangImpl->tool.getFullDependencies(
314310
database, workingDir, clangImpl->alreadySeen);
315-
316311
if (!clangDependencies) {
317312
// FIXME: Route this to a normal diagnostic.
318313
llvm::logAllUnhandledErrors(clangDependencies.takeError(), llvm::errs());
@@ -321,7 +316,6 @@ Optional<ModuleDependencies> ClangImporter::getModuleDependencies(
321316

322317
// Record module dependencies for each module we found.
323318
recordModuleDependencies(cache, *clangDependencies);
324-
325319
return cache.findDependencies(moduleName, ModuleDependenciesKind::Clang);
326320
}
327321

0 commit comments

Comments
 (0)