//===--- ClangdUnitStore.h - A container of CppFiles -------------*-C++-*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===---------------------------------------------------------------------===// #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_CLANGDUNITSTORE_H #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_CLANGDUNITSTORE_H #include "ClangdUnit.h" #include "GlobalCompilationDatabase.h" #include "Logger.h" #include "Path.h" #include "clang/Tooling/CompilationDatabase.h" #include namespace clang { namespace clangd { class Logger; /// Thread-safe mapping from FileNames to CppFile. class CppFileCollection { public: /// \p ASTCallback is called when a file is parsed synchronously. This should /// not be expensive since it blocks diagnostics. explicit CppFileCollection(ASTParsedCallback ASTCallback) : ASTCallback(std::move(ASTCallback)) {} std::shared_ptr getOrCreateFile(PathRef File, PathRef ResourceDir, GlobalCompilationDatabase &CDB, bool StorePreamblesInMemory, std::shared_ptr PCHs) { std::lock_guard Lock(Mutex); auto It = OpenedFiles.find(File); if (It == OpenedFiles.end()) { auto Command = getCompileCommand(CDB, File, ResourceDir); It = OpenedFiles .try_emplace(File, CppFile::Create(File, std::move(Command), StorePreamblesInMemory, std::move(PCHs), ASTCallback)) .first; } return It->second; } struct RecreateResult { /// A CppFile, stored in this CppFileCollection for the corresponding /// filepath after calling recreateFileIfCompileCommandChanged. std::shared_ptr FileInCollection; /// If a new CppFile had to be created to account for changed /// CompileCommand, a previous CppFile instance will be returned in this /// field. std::shared_ptr RemovedFile; }; /// Similar to getOrCreateFile, but will replace a current CppFile for \p File /// with a new one if CompileCommand, provided by \p CDB has changed. /// If a currently stored CppFile had to be replaced, the previous instance /// will be returned in RecreateResult.RemovedFile. RecreateResult recreateFileIfCompileCommandChanged( PathRef File, PathRef ResourceDir, GlobalCompilationDatabase &CDB, bool StorePreamblesInMemory, std::shared_ptr PCHs); std::shared_ptr getFile(PathRef File) { std::lock_guard Lock(Mutex); auto It = OpenedFiles.find(File); if (It == OpenedFiles.end()) return nullptr; return It->second; } /// Removes a CppFile, stored for \p File, if it's inside collection and /// returns it. std::shared_ptr removeIfPresent(PathRef File); private: tooling::CompileCommand getCompileCommand(GlobalCompilationDatabase &CDB, PathRef File, PathRef ResourceDir); bool compileCommandsAreEqual(tooling::CompileCommand const &LHS, tooling::CompileCommand const &RHS); std::mutex Mutex; llvm::StringMap> OpenedFiles; ASTParsedCallback ASTCallback; }; } // namespace clangd } // namespace clang #endif