Skip to content

Commit 36e782e

Browse files
authored
[clang][scan] Report module dependencies in topological order (#9226)
Clients of the dependency scanner may benefit from being able to process modular dependencies in topological order. The scanner already processes dependencies in this order, so it makes sense to make it easy for clients by providing an API with that guarantee. (cherry picked from commit b1795bd)
1 parent 5bc9c53 commit 36e782e

File tree

6 files changed

+32
-6
lines changed

6 files changed

+32
-6
lines changed

clang/include/clang-c/Dependencies.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,16 @@ CINDEX_LINKAGE size_t clang_experimental_DepGraph_getNumModules(CXDepGraph);
478478
CINDEX_LINKAGE CXDepGraphModule
479479
clang_experimental_DepGraph_getModule(CXDepGraph, size_t Index);
480480

481+
/**
482+
* \returns the \c CXDepGraphModule object at the given \p Index in
483+
* a topologically sorted list.
484+
*
485+
* The \c CXDepGraphModule object is only valid to use while \c CXDepGraph is
486+
* valid. Must be disposed with \c clang_experimental_DepGraphModule_dispose.
487+
*/
488+
CINDEX_LINKAGE CXDepGraphModule
489+
clang_experimental_DepGraph_getModuleTopological(CXDepGraph, size_t Index);
490+
481491
CINDEX_LINKAGE void clang_experimental_DepGraphModule_dispose(CXDepGraphModule);
482492

483493
/**

clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -640,12 +640,11 @@ ModuleDepCollectorPP::handleTopLevelModule(const Module *M) {
640640
return {};
641641

642642
// If this module has been handled already, just return its ID.
643-
auto ModI = MDC.ModularDeps.insert({M, nullptr});
644-
if (!ModI.second)
645-
return ModI.first->second->ID;
643+
if (auto ModI = MDC.ModularDeps.find(M); ModI != MDC.ModularDeps.end())
644+
return ModI->second->ID;
646645

647-
ModI.first->second = std::make_unique<ModuleDeps>();
648-
ModuleDeps &MD = *ModI.first->second;
646+
auto OwnedMD = std::make_unique<ModuleDeps>();
647+
ModuleDeps &MD = *OwnedMD;
649648

650649
MD.ID.ModuleName = M->getFullModuleName();
651650
MD.IsSystem = M->IsSystem;
@@ -756,6 +755,8 @@ ModuleDepCollectorPP::handleTopLevelModule(const Module *M) {
756755

757756
MD.BuildInfo = std::move(CI);
758757

758+
MDC.ModularDeps.insert({M, std::move(OwnedMD)});
759+
759760
return MD.ID;
760761
}
761762

clang/test/ClangScanDeps/modules-order-c-api.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,13 @@
1010
// RUN: diff %t/output1 %t/output2
1111
// RUN: diff %t/output1 %t/output3
1212

13+
// And that module dependencies are in topological order.
14+
// RUN: FileCheck --input-file %t/output1 %s
15+
// CHECK: modules
16+
// CHECK-DAG: name: FromMod1
17+
// CHECK-DAG: name: FromMod2
18+
// CHECK: name: FromMain1
19+
1320
//--- module.modulemap
1421
module FromMain1 { header "FromMain1.h" }
1522
module FromMain2 { header "FromMain2.h" }

clang/tools/c-index-test/core_main.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -801,7 +801,8 @@ static int scanDeps(ArrayRef<const char *> Args, std::string WorkingDirectory,
801801
llvm::outs() << "modules:\n";
802802
for (size_t I = 0, E = clang_experimental_DepGraph_getNumModules(Graph);
803803
I < E; ++I) {
804-
CXDepGraphModule Mod = clang_experimental_DepGraph_getModule(Graph, I);
804+
CXDepGraphModule Mod =
805+
clang_experimental_DepGraph_getModuleTopological(Graph, I);
805806
const char *Name = clang_experimental_DepGraphModule_getName(Mod);
806807
const char *ContextHash =
807808
clang_experimental_DepGraphModule_getContextHash(Mod);

clang/tools/libclang/CDependencies.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,12 @@ size_t clang_experimental_DepGraph_getNumModules(CXDepGraph Graph) {
545545

546546
CXDepGraphModule clang_experimental_DepGraph_getModule(CXDepGraph Graph,
547547
size_t Index) {
548+
return clang_experimental_DepGraph_getModuleTopological(Graph, Index);
549+
}
550+
551+
CXDepGraphModule
552+
clang_experimental_DepGraph_getModuleTopological(CXDepGraph Graph,
553+
size_t Index) {
548554
TranslationUnitDeps &TUDeps = unwrap(Graph)->TUDeps;
549555
return wrap(new DependencyGraphModule{&TUDeps.ModuleGraph[Index]});
550556
}

clang/tools/libclang/libclang.map

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,7 @@ LLVM_16 {
519519
clang_experimental_DepGraph_dispose;
520520
clang_experimental_DepGraph_getDiagnostics;
521521
clang_experimental_DepGraph_getModule;
522+
clang_experimental_DepGraph_getModuleTopological;
522523
clang_experimental_DepGraph_getNumModules;
523524
clang_experimental_DepGraph_getNumTUCommands;
524525
clang_experimental_DepGraph_getTUCommand;

0 commit comments

Comments
 (0)