aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
diff options
context:
space:
mode:
authorCyndy Ishida <cyndy_ishida@apple.com>2025-07-11 09:33:55 -0700
committerGitHub <noreply@github.com>2025-07-11 09:33:55 -0700
commit15c3793cdf947be16a4686d26998143fd6487641 (patch)
tree3868d4c5d5583edd9f775da11389b686030fe806 /clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
parent6882a30acec695beab568d5393af9bd15970d0d6 (diff)
downloadllvm-15c3793cdf947be16a4686d26998143fd6487641.zip
llvm-15c3793cdf947be16a4686d26998143fd6487641.tar.gz
llvm-15c3793cdf947be16a4686d26998143fd6487641.tar.bz2
[clang][scan-deps] Report a scanned TU's visible modules (#147969)
Clients of the dependency scanning service may need to add dependencies based on the visibility of importing modules, for example, when determining whether a Swift overlay dependency should be brought in based on whether there's a corresponding **visible** clang module for it. This patch introduces a new field `VisibleModules` that contains all the visible top-level modules in a given TU. Because visibility is determined by which headers or (sub)modules were imported, and not top-level module dependencies, the scanner now performs a separate DFS starting from what was directly imported for this computation. In my local performance testing, there was no observable performance impact. resolves: rdar://151416358 --------- Co-authored-by: Jan Svoboda <jan@svoboda.ai>
Diffstat (limited to 'clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp')
-rw-r--r--clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp32
1 files changed, 31 insertions, 1 deletions
diff --git a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
index fa86d71..37f8b94 100644
--- a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
+++ b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
@@ -673,8 +673,10 @@ void ModuleDepCollectorPP::handleImport(const Module *Imported) {
if (MDC.isPrebuiltModule(TopLevelModule))
MDC.DirectPrebuiltModularDeps.insert(
{TopLevelModule, PrebuiltModuleDep{TopLevelModule}});
- else
+ else {
MDC.DirectModularDeps.insert(TopLevelModule);
+ MDC.DirectImports.insert(Imported);
+ }
}
void ModuleDepCollectorPP::EndOfMainFile() {
@@ -706,6 +708,8 @@ void ModuleDepCollectorPP::EndOfMainFile() {
if (!MDC.isPrebuiltModule(M))
MDC.DirectModularDeps.insert(M);
+ MDC.addVisibleModules();
+
for (const Module *M : MDC.DirectModularDeps)
handleTopLevelModule(M);
@@ -727,6 +731,9 @@ void ModuleDepCollectorPP::EndOfMainFile() {
MDC.Consumer.handleDirectModuleDependency(It->second->ID);
}
+ for (auto &&I : MDC.VisibleModules)
+ MDC.Consumer.handleVisibleModule(std::string(I.getKey()));
+
for (auto &&I : MDC.FileDeps)
MDC.Consumer.handleFileDependency(I);
@@ -993,6 +1000,29 @@ bool ModuleDepCollector::isPrebuiltModule(const Module *M) {
return true;
}
+void ModuleDepCollector::addVisibleModules() {
+ llvm::DenseSet<const Module *> ImportedModules;
+ auto InsertVisibleModules = [&](const Module *M) {
+ if (ImportedModules.contains(M))
+ return;
+
+ VisibleModules.insert(M->getTopLevelModuleName());
+ SmallVector<Module *> Stack;
+ M->getExportedModules(Stack);
+ while (!Stack.empty()) {
+ const Module *CurrModule = Stack.pop_back_val();
+ if (ImportedModules.contains(CurrModule))
+ continue;
+ ImportedModules.insert(CurrModule);
+ VisibleModules.insert(CurrModule->getTopLevelModuleName());
+ CurrModule->getExportedModules(Stack);
+ }
+ };
+
+ for (const Module *Import : DirectImports)
+ InsertVisibleModules(Import);
+}
+
static StringRef makeAbsoluteAndPreferred(CompilerInstance &CI, StringRef Path,
SmallVectorImpl<char> &Storage) {
if (llvm::sys::path::is_absolute(Path) &&