diff options
Diffstat (limited to 'clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp')
-rw-r--r-- | clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp | 101 |
1 files changed, 82 insertions, 19 deletions
diff --git a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp index 422940047f2d..4f6eff799f22 100644 --- a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp +++ b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp @@ -17,12 +17,60 @@ using namespace clang; using namespace tooling; using namespace dependencies; +std::vector<std::string> ModuleDeps::getFullCommandLine( + std::function<StringRef(ClangModuleDep)> LookupPCMPath, + std::function<const ModuleDeps &(ClangModuleDep)> LookupModuleDeps) const { + std::vector<std::string> Ret = NonPathCommandLine; + + // TODO: Build full command line. That also means capturing the original + // command line into NonPathCommandLine. + + dependencies::detail::appendCommonModuleArguments( + ClangModuleDeps, LookupPCMPath, LookupModuleDeps, Ret); + + return Ret; +} + +void dependencies::detail::appendCommonModuleArguments( + llvm::ArrayRef<ClangModuleDep> Modules, + std::function<StringRef(ClangModuleDep)> LookupPCMPath, + std::function<const ModuleDeps &(ClangModuleDep)> LookupModuleDeps, + std::vector<std::string> &Result) { + llvm::StringSet<> AlreadyAdded; + + std::function<void(llvm::ArrayRef<ClangModuleDep>)> AddArgs = + [&](llvm::ArrayRef<ClangModuleDep> Modules) { + for (const ClangModuleDep &CMD : Modules) { + if (!AlreadyAdded.insert(CMD.ModuleName + CMD.ContextHash).second) + continue; + const ModuleDeps &M = LookupModuleDeps(CMD); + // Depth first traversal. + AddArgs(M.ClangModuleDeps); + Result.push_back(("-fmodule-file=" + LookupPCMPath(CMD)).str()); + if (!M.ClangModuleMapFile.empty()) { + Result.push_back("-fmodule-map-file=" + M.ClangModuleMapFile); + } + } + }; + + Result.push_back("-fno-implicit-modules"); + Result.push_back("-fno-implicit-module-maps"); + AddArgs(Modules); +} + void ModuleDepCollectorPP::FileChanged(SourceLocation Loc, FileChangeReason Reason, SrcMgr::CharacteristicKind FileType, FileID PrevFID) { if (Reason != PPCallbacks::EnterFile) return; + + // This has to be delayed as the context hash can change at the start of + // `CompilerInstance::ExecuteAction`. + if (MDC.ContextHash.empty()) { + MDC.ContextHash = Instance.getInvocation().getModuleHash(); + MDC.Consumer.handleContextHash(MDC.ContextHash); + } SourceManager &SM = Instance.getSourceManager(); @@ -37,7 +85,7 @@ void ModuleDepCollectorPP::FileChanged(SourceLocation Loc, StringRef FileName = llvm::sys::path::remove_leading_dotslash(File->getName()); - MDC.MainDeps.push_back(FileName); + MDC.MainDeps.push_back(std::string(FileName)); } void ModuleDepCollectorPP::InclusionDirective( @@ -48,9 +96,18 @@ void ModuleDepCollectorPP::InclusionDirective( if (!File && !Imported) { // This is a non-modular include that HeaderSearch failed to find. Add it // here as `FileChanged` will never see it. - MDC.MainDeps.push_back(FileName); + MDC.MainDeps.push_back(std::string(FileName)); } + handleImport(Imported); +} +void ModuleDepCollectorPP::moduleImport(SourceLocation ImportLoc, + ModuleIdPath Path, + const Module *Imported) { + handleImport(Imported); +} + +void ModuleDepCollectorPP::handleImport(const Module *Imported) { if (!Imported) return; @@ -61,8 +118,8 @@ void ModuleDepCollectorPP::InclusionDirective( void ModuleDepCollectorPP::EndOfMainFile() { FileID MainFileID = Instance.getSourceManager().getMainFileID(); - MDC.MainFile = - Instance.getSourceManager().getFileEntryForID(MainFileID)->getName(); + MDC.MainFile = std::string( + Instance.getSourceManager().getFileEntryForID(MainFileID)->getName()); for (const Module *M : DirectDeps) { handleTopLevelModule(M); @@ -71,9 +128,8 @@ void ModuleDepCollectorPP::EndOfMainFile() { for (auto &&I : MDC.Deps) MDC.Consumer.handleModuleDependency(I.second); - DependencyOutputOptions Opts; for (auto &&I : MDC.MainDeps) - MDC.Consumer.handleFileDependency(Opts, I); + MDC.Consumer.handleFileDependency(*MDC.Opts, I); } void ModuleDepCollectorPP::handleTopLevelModule(const Module *M) { @@ -92,9 +148,9 @@ void ModuleDepCollectorPP::handleTopLevelModule(const Module *M) { .getModuleMap() .getContainingModuleMapFile(M); - MD.ClangModuleMapFile = ModuleMap ? ModuleMap->getName() : ""; + MD.ClangModuleMapFile = std::string(ModuleMap ? ModuleMap->getName() : ""); MD.ModuleName = M->getFullModuleName(); - MD.ModulePCMPath = M->getASTFile()->getName(); + MD.ImplicitModulePCMPath = std::string(M->getASTFile()->getName()); MD.ContextHash = MDC.ContextHash; serialization::ModuleFile *MF = MDC.Instance.getASTReader()->getModuleManager().lookup(M->getASTFile()); @@ -103,30 +159,37 @@ void ModuleDepCollectorPP::handleTopLevelModule(const Module *M) { MD.FileDeps.insert(IF.getFile()->getName()); }); - addAllSubmoduleDeps(M, MD); + llvm::DenseSet<const Module *> AddedModules; + addAllSubmoduleDeps(M, MD, AddedModules); } -void ModuleDepCollectorPP::addAllSubmoduleDeps(const Module *M, - ModuleDeps &MD) { - addModuleDep(M, MD); +void ModuleDepCollectorPP::addAllSubmoduleDeps( + const Module *M, ModuleDeps &MD, + llvm::DenseSet<const Module *> &AddedModules) { + addModuleDep(M, MD, AddedModules); for (const Module *SubM : M->submodules()) - addAllSubmoduleDeps(SubM, MD); + addAllSubmoduleDeps(SubM, MD, AddedModules); } -void ModuleDepCollectorPP::addModuleDep(const Module *M, ModuleDeps &MD) { +void ModuleDepCollectorPP::addModuleDep( + const Module *M, ModuleDeps &MD, + llvm::DenseSet<const Module *> &AddedModules) { for (const Module *Import : M->Imports) { if (Import->getTopLevelModule() != M->getTopLevelModule()) { - MD.ClangModuleDeps.insert(Import->getTopLevelModuleName()); + if (AddedModules.insert(Import->getTopLevelModule()).second) + MD.ClangModuleDeps.push_back( + {std::string(Import->getTopLevelModuleName()), + Instance.getInvocation().getModuleHash()}); handleTopLevelModule(Import->getTopLevelModule()); } } } -ModuleDepCollector::ModuleDepCollector(CompilerInstance &I, - DependencyConsumer &C) - : Instance(I), Consumer(C), ContextHash(I.getInvocation().getModuleHash()) { -} +ModuleDepCollector::ModuleDepCollector( + std::unique_ptr<DependencyOutputOptions> Opts, CompilerInstance &I, + DependencyConsumer &C) + : Instance(I), Consumer(C), Opts(std::move(Opts)) {} void ModuleDepCollector::attachToPreprocessor(Preprocessor &PP) { PP.addPPCallbacks(std::make_unique<ModuleDepCollectorPP>(Instance, *this)); |