//===--- GlobalCompilationDatabase.h ----------------------------*- 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_GLOBALCOMPILATIONDATABASE_H #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_GLOBALCOMPILATIONDATABASE_H #include "Path.h" #include "llvm/ADT/StringMap.h" #include #include #include namespace clang { namespace tooling { class CompilationDatabase; struct CompileCommand; } // namespace tooling namespace clangd { class Logger; /// Provides compilation arguments used for parsing C and C++ files. class GlobalCompilationDatabase { public: virtual ~GlobalCompilationDatabase() = default; /// If there are any known-good commands for building this file, returns one. virtual llvm::Optional getCompileCommand(PathRef File) const = 0; /// Makes a guess at how to build a file. /// The default implementation just runs clang on the file. /// Clangd should treat the results as unreliable. virtual tooling::CompileCommand getFallbackCommand(PathRef File) const; /// FIXME(ibiryukov): add facilities to track changes to compilation flags of /// existing targets. }; /// Gets compile args from tooling::CompilationDatabases built for parent /// directories. class DirectoryBasedGlobalCompilationDatabase : public GlobalCompilationDatabase { public: DirectoryBasedGlobalCompilationDatabase( llvm::Optional CompileCommandsDir); ~DirectoryBasedGlobalCompilationDatabase() override; /// Scans File's parents looking for compilation databases. /// Any extra flags will be added. llvm::Optional getCompileCommand(PathRef File) const override; /// Uses the default fallback command, adding any extra flags. tooling::CompileCommand getFallbackCommand(PathRef File) const override; /// Set the compile commands directory to \p P. void setCompileCommandsDir(Path P); /// Sets the extra flags that should be added to a file. void setExtraFlagsForFile(PathRef File, std::vector ExtraFlags); private: tooling::CompilationDatabase *getCDBForFile(PathRef File) const; tooling::CompilationDatabase *getCDBInDirLocked(PathRef File) const; void addExtraFlags(PathRef File, tooling::CompileCommand &C) const; mutable std::mutex Mutex; /// Caches compilation databases loaded from directories(keys are /// directories). mutable llvm::StringMap> CompilationDatabases; /// Stores extra flags per file. llvm::StringMap> ExtraFlagsForFile; /// Used for command argument pointing to folder where compile_commands.json /// is located. llvm::Optional CompileCommandsDir; }; /// A wrapper around GlobalCompilationDatabase that caches the compile commands. /// Note that only results of getCompileCommand are cached. class CachingCompilationDb : public GlobalCompilationDatabase { public: explicit CachingCompilationDb(const GlobalCompilationDatabase &InnerCDB); /// Gets compile command for \p File from cache or CDB if it's not in the /// cache. llvm::Optional getCompileCommand(PathRef File) const override; /// Forwards to the inner CDB. Results of this function are not cached. tooling::CompileCommand getFallbackCommand(PathRef File) const override; /// Removes an entry for \p File if it's present in the cache. void invalidate(PathRef File); /// Removes all cached compile commands. void clear(); private: const GlobalCompilationDatabase &InnerCDB; mutable std::mutex Mut; mutable llvm::StringMap> Cached; /* GUARDED_BY(Mut) */ }; } // namespace clangd } // namespace clang #endif