https://github.com/qiongsiwu created https://github.com/llvm/llvm-project/pull/129915
Currently `DependencyScanningTool::getModuleDependencies` takes a single `ModuleName` and if we have a list of module names to process for the same compilation, we invoke `getModuleDependencies` multiple times and sets up the identical `CompilerInvocation` multiple times (in `DependencyScanningAction::runInvocation`). This PR revises `getModuleDependencies` so it can take a list of module names. rdar://136303612 >From 7f29cb0c9e422f00ce5b6b26af8ebfb228b59830 Mon Sep 17 00:00:00 2001 From: Qiongsi Wu <qiongsi...@apple.com> Date: Wed, 5 Mar 2025 11:16:38 -0800 Subject: [PATCH] Changing DependencyScanningTool::getModuleDependencies to take a list of module names instead of one module name. --- .../include/clang/Frontend/FrontendActions.h | 6 ++-- .../DependencyScanningTool.h | 14 ++++---- .../DependencyScanningWorker.h | 6 ++-- clang/lib/Frontend/FrontendActions.cpp | 20 +++++++---- .../DependencyScanningTool.cpp | 9 +++-- .../DependencyScanningWorker.cpp | 35 +++++++++++-------- clang/tools/clang-scan-deps/ClangScanDeps.cpp | 4 +-- 7 files changed, 56 insertions(+), 38 deletions(-) diff --git a/clang/include/clang/Frontend/FrontendActions.h b/clang/include/clang/Frontend/FrontendActions.h index a620ddfc40447..c80422e97462d 100644 --- a/clang/include/clang/Frontend/FrontendActions.h +++ b/clang/include/clang/Frontend/FrontendActions.h @@ -320,12 +320,12 @@ class PrintPreprocessedAction : public PreprocessorFrontendAction { }; class GetDependenciesByModuleNameAction : public PreprocessOnlyAction { - StringRef ModuleName; + ArrayRef<StringRef> ModuleNames; void ExecuteAction() override; public: - GetDependenciesByModuleNameAction(StringRef ModuleName) - : ModuleName(ModuleName) {} + GetDependenciesByModuleNameAction(ArrayRef<StringRef> ModuleNames) + : ModuleNames(ModuleNames) {} }; } // end namespace clang diff --git a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h index d13c3ee76d74f..25473b5c2500f 100644 --- a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h +++ b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h @@ -144,12 +144,14 @@ class DependencyScanningTool { std::optional<llvm::MemoryBufferRef> TUBuffer = std::nullopt); /// Given a compilation context specified via the Clang driver command-line, - /// gather modular dependencies of module with the given name, and return the - /// information needed for explicit build. - llvm::Expected<ModuleDepsGraph> getModuleDependencies( - StringRef ModuleName, const std::vector<std::string> &CommandLine, - StringRef CWD, const llvm::DenseSet<ModuleID> &AlreadySeen, - LookupModuleOutputCallback LookupModuleOutput); + /// gather modular dependencies of modules specified by the the given list of + /// names, and return the information needed for explicit build. + llvm::Expected<ModuleDepsGraph> + getModuleDependencies(ArrayRef<StringRef> ModuleNames, + const std::vector<std::string> &CommandLine, + StringRef CWD, + const llvm::DenseSet<ModuleID> &AlreadySeen, + LookupModuleOutputCallback LookupModuleOutput); llvm::vfs::FileSystem &getWorkerVFS() const { return Worker.getVFS(); } diff --git a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h index 5f0b983ebb58f..901f42715e6e6 100644 --- a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h +++ b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h @@ -111,7 +111,7 @@ class DependencyScanningWorker { DependencyConsumer &DepConsumer, DependencyActionController &Controller, DiagnosticConsumer &DiagConsumer, - StringRef ModuleName); + ArrayRef<StringRef> ModuleNames); /// Run the dependency scanning tool for a given clang driver command-line /// for a specific translation unit via file system or memory buffer. @@ -132,7 +132,7 @@ class DependencyScanningWorker { const std::vector<std::string> &CommandLine, DependencyConsumer &Consumer, DependencyActionController &Controller, - StringRef ModuleName); + ArrayRef<StringRef> ModuleNames); llvm::vfs::FileSystem &getVFS() const { return *BaseFS; } @@ -156,7 +156,7 @@ class DependencyScanningWorker { DependencyActionController &Controller, DiagnosticConsumer &DC, llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS, - std::optional<StringRef> ModuleName); + std::optional<ArrayRef<StringRef>> ModuleNames); }; } // end namespace dependencies diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp index 1ea4a2e9e88cf..5c6419bd4e677 100644 --- a/clang/lib/Frontend/FrontendActions.cpp +++ b/clang/lib/Frontend/FrontendActions.cpp @@ -1213,11 +1213,17 @@ void GetDependenciesByModuleNameAction::ExecuteAction() { Preprocessor &PP = CI.getPreprocessor(); SourceManager &SM = PP.getSourceManager(); FileID MainFileID = SM.getMainFileID(); - SourceLocation FileStart = SM.getLocForStartOfFile(MainFileID); - SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> Path; - IdentifierInfo *ModuleID = PP.getIdentifierInfo(ModuleName); - Path.push_back(std::make_pair(ModuleID, FileStart)); - auto ModResult = CI.loadModule(FileStart, Path, Module::Hidden, false); - PPCallbacks *CB = PP.getPPCallbacks(); - CB->moduleImport(SourceLocation(), Path, ModResult); + SourceLocation SLoc = SM.getLocForStartOfFile(MainFileID); + for (auto ModuleName : ModuleNames) { + SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> Path; + IdentifierInfo *ModuleID = PP.getIdentifierInfo(ModuleName); + Path.push_back(std::make_pair(ModuleID, SLoc)); + auto ModResult = CI.loadModule(SLoc, Path, Module::Hidden, false); + PPCallbacks *CB = PP.getPPCallbacks(); + CB->moduleImport(SourceLocation(), Path, ModResult); + // FIXME: how do you know that this offset is correct? + SLoc = SLoc.getLocWithOffset(1); + assert(SLoc <= SM.getLocForEndOfFile(MainFileID) && + "Import location extends past file"); + } } diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp index 2b4c2bb76434a..e7b6f87e2db11 100644 --- a/clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp +++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp @@ -155,13 +155,16 @@ DependencyScanningTool::getTranslationUnitDependencies( } llvm::Expected<ModuleDepsGraph> DependencyScanningTool::getModuleDependencies( - StringRef ModuleName, const std::vector<std::string> &CommandLine, - StringRef CWD, const llvm::DenseSet<ModuleID> &AlreadySeen, + ArrayRef<StringRef> ModuleNames, + const std::vector<std::string> &CommandLine, StringRef CWD, + const llvm::DenseSet<ModuleID> &AlreadySeen, LookupModuleOutputCallback LookupModuleOutput) { FullDependencyConsumer Consumer(AlreadySeen); CallbackActionController Controller(LookupModuleOutput); + + assert(ModuleNames.size() && "GettingModuleDependencies for an empty list!"); llvm::Error Result = Worker.computeDependencies(CWD, CommandLine, Consumer, - Controller, ModuleName); + Controller, ModuleNames); if (Result) return std::move(Result); return Consumer.takeModuleGraphDeps(); diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp index 697f26ee5d12f..f2c5a0716126a 100644 --- a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp +++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp @@ -287,10 +287,11 @@ class DependencyScanningAction : public tooling::ToolAction { DependencyScanningService &Service, StringRef WorkingDirectory, DependencyConsumer &Consumer, DependencyActionController &Controller, llvm::IntrusiveRefCntPtr<DependencyScanningWorkerFilesystem> DepFS, - bool DisableFree, std::optional<StringRef> ModuleName = std::nullopt) + bool DisableFree, + std::optional<ArrayRef<StringRef>> ModuleNames = std::nullopt) : Service(Service), WorkingDirectory(WorkingDirectory), Consumer(Consumer), Controller(Controller), DepFS(std::move(DepFS)), - DisableFree(DisableFree), ModuleName(ModuleName) {} + DisableFree(DisableFree), ModuleNames(ModuleNames) {} bool runInvocation(std::shared_ptr<CompilerInvocation> Invocation, FileManager *DriverFileMgr, @@ -431,8 +432,9 @@ class DependencyScanningAction : public tooling::ToolAction { if (Service.getFormat() == ScanningOutputFormat::P1689) Action = std::make_unique<PreprocessOnlyAction>(); - else if (ModuleName) - Action = std::make_unique<GetDependenciesByModuleNameAction>(*ModuleName); + else if (ModuleNames) + Action = + std::make_unique<GetDependenciesByModuleNameAction>(*ModuleNames); else Action = std::make_unique<ReadPCHAndPreprocessAction>(); @@ -478,7 +480,7 @@ class DependencyScanningAction : public tooling::ToolAction { DependencyActionController &Controller; llvm::IntrusiveRefCntPtr<DependencyScanningWorkerFilesystem> DepFS; bool DisableFree; - std::optional<StringRef> ModuleName; + std::optional<ArrayRef<StringRef>> ModuleNames; std::optional<CompilerInstance> ScanInstanceStorage; std::shared_ptr<ModuleDepCollector> MDC; std::vector<std::string> LastCC1Arguments; @@ -546,7 +548,7 @@ llvm::Error DependencyScanningWorker::computeDependencies( llvm::Error DependencyScanningWorker::computeDependencies( StringRef WorkingDirectory, const std::vector<std::string> &CommandLine, DependencyConsumer &Consumer, DependencyActionController &Controller, - StringRef ModuleName) { + ArrayRef<StringRef> ModuleNames) { // Capture the emitted diagnostics and report them to the client // in the case of a failure. std::string DiagnosticOutput; @@ -555,7 +557,7 @@ llvm::Error DependencyScanningWorker::computeDependencies( TextDiagnosticPrinter DiagPrinter(DiagnosticsOS, DiagOpts.release()); if (computeDependencies(WorkingDirectory, CommandLine, Consumer, Controller, - DiagPrinter, ModuleName)) + DiagPrinter, ModuleNames)) return llvm::Error::success(); return llvm::make_error<llvm::StringError>(DiagnosticsOS.str(), llvm::inconvertibleErrorCode()); @@ -625,7 +627,7 @@ bool DependencyScanningWorker::scanDependencies( StringRef WorkingDirectory, const std::vector<std::string> &CommandLine, DependencyConsumer &Consumer, DependencyActionController &Controller, DiagnosticConsumer &DC, llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS, - std::optional<StringRef> ModuleName) { + std::optional<ArrayRef<StringRef>> ModuleNames) { auto FileMgr = llvm::makeIntrusiveRefCnt<FileManager>(FileSystemOptions{}, FS); @@ -648,7 +650,7 @@ bool DependencyScanningWorker::scanDependencies( // always true for a driver invocation. bool DisableFree = true; DependencyScanningAction Action(Service, WorkingDirectory, Consumer, - Controller, DepFS, DisableFree, ModuleName); + Controller, DepFS, DisableFree, ModuleNames); bool Success = false; if (CommandLine[1] == "-cc1") { @@ -729,13 +731,14 @@ bool DependencyScanningWorker::computeDependencies( auto &FinalFS = ModifiedFS ? ModifiedFS : BaseFS; return scanDependencies(WorkingDirectory, FinalCommandLine, Consumer, - Controller, DC, FinalFS, /*ModuleName=*/std::nullopt); + Controller, DC, FinalFS, + /*ModuleNames=*/std::nullopt); } bool DependencyScanningWorker::computeDependencies( StringRef WorkingDirectory, const std::vector<std::string> &CommandLine, DependencyConsumer &Consumer, DependencyActionController &Controller, - DiagnosticConsumer &DC, StringRef ModuleName) { + DiagnosticConsumer &DC, ArrayRef<StringRef> ModuleNames) { // Reset what might have been modified in the previous worker invocation. BaseFS->setCurrentWorkingDirectory(WorkingDirectory); @@ -748,9 +751,13 @@ bool DependencyScanningWorker::computeDependencies( InMemoryFS->setCurrentWorkingDirectory(WorkingDirectory); SmallString<128> FakeInputPath; // TODO: We should retry the creation if the path already exists. - llvm::sys::fs::createUniquePath(ModuleName + "-%%%%%%%%.input", FakeInputPath, + // FIXME: should we create files for multiple modules? I think so? + llvm::sys::fs::createUniquePath(ModuleNames[0] + "-%%%%%%%%.input", + FakeInputPath, /*MakeAbsolute=*/false); - InMemoryFS->addFile(FakeInputPath, 0, llvm::MemoryBuffer::getMemBuffer("")); + std::string FakeString(ModuleNames.size(), ' '); + InMemoryFS->addFile(FakeInputPath, 0, + llvm::MemoryBuffer::getMemBuffer(FakeString)); llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> InMemoryOverlay = InMemoryFS; OverlayFS->pushOverlay(InMemoryOverlay); @@ -758,7 +765,7 @@ bool DependencyScanningWorker::computeDependencies( ModifiedCommandLine.emplace_back(FakeInputPath); return scanDependencies(WorkingDirectory, ModifiedCommandLine, Consumer, - Controller, DC, OverlayFS, ModuleName); + Controller, DC, OverlayFS, ModuleNames); } DependencyActionController::~DependencyActionController() {} diff --git a/clang/tools/clang-scan-deps/ClangScanDeps.cpp b/clang/tools/clang-scan-deps/ClangScanDeps.cpp index 3bdeb461e4bfa..8c857418b26ea 100644 --- a/clang/tools/clang-scan-deps/ClangScanDeps.cpp +++ b/clang/tools/clang-scan-deps/ClangScanDeps.cpp @@ -1025,8 +1025,8 @@ int clang_scan_deps_main(int argc, char **argv, const llvm::ToolContext &) { } } else if (ModuleName) { auto MaybeModuleDepsGraph = WorkerTool.getModuleDependencies( - *ModuleName, Input->CommandLine, CWD, AlreadySeenModules, - LookupOutput); + ArrayRef<StringRef>({*ModuleName}), Input->CommandLine, CWD, + AlreadySeenModules, LookupOutput); if (handleModuleResult(*ModuleName, MaybeModuleDepsGraph, *FD, LocalIndex, DependencyOS, Errs)) HadErrors = true; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits