Line data Source code
1 : //===--- GlobalCompilationDatabase.h -----------------------------*- C++-*-===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 :
10 : #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_GLOBALCOMPILATIONDATABASE_H
11 : #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_GLOBALCOMPILATIONDATABASE_H
12 :
13 : #include "Path.h"
14 : #include "llvm/ADT/StringMap.h"
15 : #include <memory>
16 : #include <mutex>
17 : #include <vector>
18 :
19 : namespace clang {
20 :
21 : namespace tooling {
22 : class CompilationDatabase;
23 : struct CompileCommand;
24 : } // namespace tooling
25 :
26 : namespace clangd {
27 :
28 : class Logger;
29 :
30 : /// Provides compilation arguments used for parsing C and C++ files.
31 : class GlobalCompilationDatabase {
32 : public:
33 0 : virtual ~GlobalCompilationDatabase() = default;
34 :
35 : /// If there are any known-good commands for building this file, returns one.
36 : virtual llvm::Optional<tooling::CompileCommand>
37 : getCompileCommand(PathRef File) const = 0;
38 :
39 : /// Makes a guess at how to build a file.
40 : /// The default implementation just runs clang on the file.
41 : /// Clangd should treat the results as unreliable.
42 : virtual tooling::CompileCommand getFallbackCommand(PathRef File) const;
43 :
44 : /// FIXME(ibiryukov): add facilities to track changes to compilation flags of
45 : /// existing targets.
46 : };
47 :
48 : /// Gets compile args from tooling::CompilationDatabases built for parent
49 : /// directories.
50 : class DirectoryBasedGlobalCompilationDatabase
51 : : public GlobalCompilationDatabase {
52 : public:
53 : DirectoryBasedGlobalCompilationDatabase(
54 : llvm::Optional<Path> CompileCommandsDir);
55 : ~DirectoryBasedGlobalCompilationDatabase() override;
56 :
57 : /// Scans File's parents looking for compilation databases.
58 : /// Any extra flags will be added.
59 : llvm::Optional<tooling::CompileCommand>
60 : getCompileCommand(PathRef File) const override;
61 :
62 : /// Uses the default fallback command, adding any extra flags.
63 : tooling::CompileCommand getFallbackCommand(PathRef File) const override;
64 :
65 : /// Set the compile commands directory to \p P.
66 : void setCompileCommandsDir(Path P);
67 :
68 : /// Sets the extra flags that should be added to a file.
69 : void setExtraFlagsForFile(PathRef File, std::vector<std::string> ExtraFlags);
70 :
71 : private:
72 : tooling::CompilationDatabase *getCDBForFile(PathRef File) const;
73 : tooling::CompilationDatabase *getCDBInDirLocked(PathRef File) const;
74 : void addExtraFlags(PathRef File, tooling::CompileCommand &C) const;
75 :
76 : mutable std::mutex Mutex;
77 : /// Caches compilation databases loaded from directories(keys are
78 : /// directories).
79 : mutable llvm::StringMap<std::unique_ptr<clang::tooling::CompilationDatabase>>
80 : CompilationDatabases;
81 :
82 : /// Stores extra flags per file.
83 : llvm::StringMap<std::vector<std::string>> ExtraFlagsForFile;
84 : /// Used for command argument pointing to folder where compile_commands.json
85 : /// is located.
86 : llvm::Optional<Path> CompileCommandsDir;
87 : };
88 :
89 : /// A wrapper around GlobalCompilationDatabase that caches the compile commands.
90 : /// Note that only results of getCompileCommand are cached.
91 : class CachingCompilationDb : public GlobalCompilationDatabase {
92 : public:
93 : explicit CachingCompilationDb(const GlobalCompilationDatabase &InnerCDB);
94 :
95 : /// Gets compile command for \p File from cache or CDB if it's not in the
96 : /// cache.
97 : llvm::Optional<tooling::CompileCommand>
98 : getCompileCommand(PathRef File) const override;
99 :
100 : /// Forwards to the inner CDB. Results of this function are not cached.
101 : tooling::CompileCommand getFallbackCommand(PathRef File) const override;
102 :
103 : /// Removes an entry for \p File if it's present in the cache.
104 : void invalidate(PathRef File);
105 :
106 : /// Removes all cached compile commands.
107 : void clear();
108 :
109 : private:
110 : const GlobalCompilationDatabase &InnerCDB;
111 : mutable std::mutex Mut;
112 : mutable llvm::StringMap<llvm::Optional<tooling::CompileCommand>>
113 : Cached; /* GUARDED_BY(Mut) */
114 : };
115 :
116 : /// Gets compile args from an in-memory mapping based on a filepath. Typically
117 : /// used by clients who provide the compile commands themselves.
118 : class InMemoryCompilationDb : public GlobalCompilationDatabase {
119 : public:
120 : /// Gets compile command for \p File from the stored mapping.
121 : llvm::Optional<tooling::CompileCommand>
122 : getCompileCommand(PathRef File) const override;
123 :
124 : /// Sets the compilation command for a particular file.
125 : ///
126 : /// \returns True if the File had no compilation command before.
127 : bool setCompilationCommandForFile(PathRef File,
128 : tooling::CompileCommand CompilationCommand);
129 :
130 : /// Removes the compilation command for \p File if it's present in the
131 : /// mapping.
132 : void invalidate(PathRef File);
133 :
134 : private:
135 : mutable std::mutex Mutex;
136 : llvm::StringMap<tooling::CompileCommand> Commands; /* GUARDED_BY(Mut) */
137 : };
138 :
139 : } // namespace clangd
140 : } // namespace clang
141 :
142 : #endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_GLOBALCOMPILATIONDATABASE_H
|