================ @@ -316,36 +294,205 @@ llvm::Error buildModuleFile(llvm::StringRef ModuleName, if (Clang->getDiagnostics().hasErrorOccurred()) return llvm::createStringError("Compilation failed"); - BuiltModuleFiles.addModuleFile(ModuleName, Inputs.CompileCommand.Output); - return llvm::Error::success(); + return ModuleFile{ModuleName, Inputs.CompileCommand.Output}; +} + +bool ReusablePrerequisiteModules::canReuse( + const CompilerInvocation &CI, + llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) const { + if (RequiredModules.empty()) + return true; + + SmallVector<StringRef> BMIPaths; + for (auto &MF : RequiredModules) + BMIPaths.push_back(MF->getModuleFilePath()); + return IsModuleFilesUpToDate(BMIPaths, *this, VFS); +} + +class ModuleFileCache { +public: + ModuleFileCache(const GlobalCompilationDatabase &CDB) : CDB(CDB) {} + + llvm::Error + getOrBuildModuleFile(StringRef ModuleName, const ThreadsafeFS &TFS, + ProjectModules &MDB, + ReusablePrerequisiteModules &RequiredModules); + const GlobalCompilationDatabase &getCDB() const { return CDB; } + + std::shared_ptr<ModuleFile> + getValidModuleFile(StringRef ModuleName, ProjectModules &MDB, + const ThreadsafeFS &TFS, + PrerequisiteModules &BuiltModuleFiles); + + void add(StringRef ModuleName, std::shared_ptr<ModuleFile> ModuleFile) { + std::lock_guard<std::mutex> _(ModuleFilesMutex); + + ModuleFiles.insert_or_assign(ModuleName, ModuleFile); + } + +private: + const GlobalCompilationDatabase &CDB; + + llvm::StringMap<std::shared_ptr<ModuleFile>> ModuleFiles; + // Mutex to guard accesses to ModuleFiles. + std::mutex ModuleFilesMutex; +}; + +/// Collect the directly and indirectly required module names for \param +/// ModuleName. The \param ModuleName is guaranteed to be the first element in +/// \param ModuleNames. +void getAllRequiredModules(ProjectModules &MDB, StringRef ModuleName, + llvm::SmallVector<StringRef> &ModuleNames) { + std::queue<StringRef> Worklist; + llvm::StringSet<> ModuleNamesSet; + Worklist.push(ModuleName); + + while (!Worklist.empty()) { + StringRef CurrentModule = Worklist.front(); + Worklist.pop(); + + if (!ModuleNamesSet.insert(CurrentModule).second) + continue; + + ModuleNames.push_back(CurrentModule); + + for (StringRef RequiredModuleName : + MDB.getRequiredModules(MDB.getSourceForModuleName(CurrentModule))) + if (!ModuleNamesSet.contains(RequiredModuleName)) ---------------- kadircet wrote:
you're checking if `ModuleNamesSet` contains an item, but inserting into `Worklist`. as a result, you'll have duplicate module-names in `Worklist` until you process them. hence I am suggesting `ModuleNamesSet.insert(RequiredModuleName)` here instead, to make sure we don't have duplicates in the queue. https://github.com/llvm/llvm-project/pull/106683 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits