mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[Dependency Scanner] Use pragma clang module import in the hack file used to invoke the clang dependency scanner.
Using `@import` does not woth in C-mode(`-disable-objc-interop`), so C modules cannot be found in this mode. This also means the dependency scanner is not able to invoke the Clang dependency scanner tool on Linux at all.
This commit is contained in:
@@ -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<std::string> importHackFileCache;
|
||||
|
||||
public:
|
||||
/// Set containing all of the Clang modules that have already been seen.
|
||||
@@ -43,38 +43,41 @@ public:
|
||||
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<StringRef> getImportHackFile();
|
||||
llvm::ErrorOr<StringRef> 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<StringRef> ClangModuleDependenciesCacheImpl::getImportHackFile() {
|
||||
if (!importHackFile.empty())
|
||||
return importHackFile;
|
||||
llvm::ErrorOr<StringRef> 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<ModuleDependencies> 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<ModuleDependencies> 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<ModuleDependencies> 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<ModuleDependencies> ClangImporter::getModuleDependencies(
|
||||
|
||||
// Record module dependencies for each module we found.
|
||||
recordModuleDependencies(cache, *clangDependencies);
|
||||
|
||||
return cache.findDependencies(moduleName, ModuleDependenciesKind::Clang);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user