1f4a2713aSLionel Sambuc //===--- CompilationDatabase.cpp - ----------------------------------------===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc //                     The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc //
10f4a2713aSLionel Sambuc //  This file contains implementations of the CompilationDatabase base class
11f4a2713aSLionel Sambuc //  and the FixedCompilationDatabase.
12f4a2713aSLionel Sambuc //
13f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
14f4a2713aSLionel Sambuc 
15f4a2713aSLionel Sambuc #include "clang/Tooling/CompilationDatabase.h"
16f4a2713aSLionel Sambuc #include "clang/Basic/Diagnostic.h"
17*0a6a1f1dSLionel Sambuc #include "clang/Basic/DiagnosticOptions.h"
18f4a2713aSLionel Sambuc #include "clang/Driver/Action.h"
19*0a6a1f1dSLionel Sambuc #include "clang/Driver/Compilation.h"
20f4a2713aSLionel Sambuc #include "clang/Driver/Driver.h"
21f4a2713aSLionel Sambuc #include "clang/Driver/DriverDiagnostic.h"
22f4a2713aSLionel Sambuc #include "clang/Driver/Job.h"
23f4a2713aSLionel Sambuc #include "clang/Frontend/TextDiagnosticPrinter.h"
24*0a6a1f1dSLionel Sambuc #include "clang/Tooling/CompilationDatabasePluginRegistry.h"
25*0a6a1f1dSLionel Sambuc #include "clang/Tooling/Tooling.h"
26*0a6a1f1dSLionel Sambuc #include "llvm/ADT/SmallString.h"
27f4a2713aSLionel Sambuc #include "llvm/Option/Arg.h"
28*0a6a1f1dSLionel Sambuc #include "llvm/Support/Host.h"
29*0a6a1f1dSLionel Sambuc #include "llvm/Support/Path.h"
30*0a6a1f1dSLionel Sambuc #include <sstream>
31*0a6a1f1dSLionel Sambuc #include <system_error>
32f4a2713aSLionel Sambuc 
33f4a2713aSLionel Sambuc namespace clang {
34f4a2713aSLionel Sambuc namespace tooling {
35f4a2713aSLionel Sambuc 
~CompilationDatabase()36f4a2713aSLionel Sambuc CompilationDatabase::~CompilationDatabase() {}
37f4a2713aSLionel Sambuc 
38*0a6a1f1dSLionel Sambuc std::unique_ptr<CompilationDatabase>
loadFromDirectory(StringRef BuildDirectory,std::string & ErrorMessage)39f4a2713aSLionel Sambuc CompilationDatabase::loadFromDirectory(StringRef BuildDirectory,
40f4a2713aSLionel Sambuc                                        std::string &ErrorMessage) {
41f4a2713aSLionel Sambuc   std::stringstream ErrorStream;
42f4a2713aSLionel Sambuc   for (CompilationDatabasePluginRegistry::iterator
43f4a2713aSLionel Sambuc        It = CompilationDatabasePluginRegistry::begin(),
44f4a2713aSLionel Sambuc        Ie = CompilationDatabasePluginRegistry::end();
45f4a2713aSLionel Sambuc        It != Ie; ++It) {
46f4a2713aSLionel Sambuc     std::string DatabaseErrorMessage;
47*0a6a1f1dSLionel Sambuc     std::unique_ptr<CompilationDatabasePlugin> Plugin(It->instantiate());
48*0a6a1f1dSLionel Sambuc     if (std::unique_ptr<CompilationDatabase> DB =
49f4a2713aSLionel Sambuc             Plugin->loadFromDirectory(BuildDirectory, DatabaseErrorMessage))
50f4a2713aSLionel Sambuc       return DB;
51f4a2713aSLionel Sambuc     ErrorStream << It->getName() << ": " << DatabaseErrorMessage << "\n";
52f4a2713aSLionel Sambuc   }
53f4a2713aSLionel Sambuc   ErrorMessage = ErrorStream.str();
54*0a6a1f1dSLionel Sambuc   return nullptr;
55f4a2713aSLionel Sambuc }
56f4a2713aSLionel Sambuc 
57*0a6a1f1dSLionel Sambuc static std::unique_ptr<CompilationDatabase>
findCompilationDatabaseFromDirectory(StringRef Directory,std::string & ErrorMessage)58f4a2713aSLionel Sambuc findCompilationDatabaseFromDirectory(StringRef Directory,
59f4a2713aSLionel Sambuc                                      std::string &ErrorMessage) {
60f4a2713aSLionel Sambuc   std::stringstream ErrorStream;
61f4a2713aSLionel Sambuc   bool HasErrorMessage = false;
62f4a2713aSLionel Sambuc   while (!Directory.empty()) {
63f4a2713aSLionel Sambuc     std::string LoadErrorMessage;
64f4a2713aSLionel Sambuc 
65*0a6a1f1dSLionel Sambuc     if (std::unique_ptr<CompilationDatabase> DB =
66f4a2713aSLionel Sambuc             CompilationDatabase::loadFromDirectory(Directory, LoadErrorMessage))
67f4a2713aSLionel Sambuc       return DB;
68f4a2713aSLionel Sambuc 
69f4a2713aSLionel Sambuc     if (!HasErrorMessage) {
70f4a2713aSLionel Sambuc       ErrorStream << "No compilation database found in " << Directory.str()
71f4a2713aSLionel Sambuc                   << " or any parent directory\n" << LoadErrorMessage;
72f4a2713aSLionel Sambuc       HasErrorMessage = true;
73f4a2713aSLionel Sambuc     }
74f4a2713aSLionel Sambuc 
75f4a2713aSLionel Sambuc     Directory = llvm::sys::path::parent_path(Directory);
76f4a2713aSLionel Sambuc   }
77f4a2713aSLionel Sambuc   ErrorMessage = ErrorStream.str();
78*0a6a1f1dSLionel Sambuc   return nullptr;
79f4a2713aSLionel Sambuc }
80f4a2713aSLionel Sambuc 
81*0a6a1f1dSLionel Sambuc std::unique_ptr<CompilationDatabase>
autoDetectFromSource(StringRef SourceFile,std::string & ErrorMessage)82f4a2713aSLionel Sambuc CompilationDatabase::autoDetectFromSource(StringRef SourceFile,
83f4a2713aSLionel Sambuc                                           std::string &ErrorMessage) {
84f4a2713aSLionel Sambuc   SmallString<1024> AbsolutePath(getAbsolutePath(SourceFile));
85f4a2713aSLionel Sambuc   StringRef Directory = llvm::sys::path::parent_path(AbsolutePath);
86f4a2713aSLionel Sambuc 
87*0a6a1f1dSLionel Sambuc   std::unique_ptr<CompilationDatabase> DB =
88*0a6a1f1dSLionel Sambuc       findCompilationDatabaseFromDirectory(Directory, ErrorMessage);
89f4a2713aSLionel Sambuc 
90f4a2713aSLionel Sambuc   if (!DB)
91f4a2713aSLionel Sambuc     ErrorMessage = ("Could not auto-detect compilation database for file \"" +
92f4a2713aSLionel Sambuc                    SourceFile + "\"\n" + ErrorMessage).str();
93f4a2713aSLionel Sambuc   return DB;
94f4a2713aSLionel Sambuc }
95f4a2713aSLionel Sambuc 
96*0a6a1f1dSLionel Sambuc std::unique_ptr<CompilationDatabase>
autoDetectFromDirectory(StringRef SourceDir,std::string & ErrorMessage)97f4a2713aSLionel Sambuc CompilationDatabase::autoDetectFromDirectory(StringRef SourceDir,
98f4a2713aSLionel Sambuc                                              std::string &ErrorMessage) {
99f4a2713aSLionel Sambuc   SmallString<1024> AbsolutePath(getAbsolutePath(SourceDir));
100f4a2713aSLionel Sambuc 
101*0a6a1f1dSLionel Sambuc   std::unique_ptr<CompilationDatabase> DB =
102*0a6a1f1dSLionel Sambuc       findCompilationDatabaseFromDirectory(AbsolutePath, ErrorMessage);
103f4a2713aSLionel Sambuc 
104f4a2713aSLionel Sambuc   if (!DB)
105f4a2713aSLionel Sambuc     ErrorMessage = ("Could not auto-detect compilation database from directory \"" +
106f4a2713aSLionel Sambuc                    SourceDir + "\"\n" + ErrorMessage).str();
107f4a2713aSLionel Sambuc   return DB;
108f4a2713aSLionel Sambuc }
109f4a2713aSLionel Sambuc 
~CompilationDatabasePlugin()110f4a2713aSLionel Sambuc CompilationDatabasePlugin::~CompilationDatabasePlugin() {}
111f4a2713aSLionel Sambuc 
112f4a2713aSLionel Sambuc // Helper for recursively searching through a chain of actions and collecting
113f4a2713aSLionel Sambuc // all inputs, direct and indirect, of compile jobs.
114f4a2713aSLionel Sambuc struct CompileJobAnalyzer {
runclang::tooling::CompileJobAnalyzer115f4a2713aSLionel Sambuc   void run(const driver::Action *A) {
116f4a2713aSLionel Sambuc     runImpl(A, false);
117f4a2713aSLionel Sambuc   }
118f4a2713aSLionel Sambuc 
119f4a2713aSLionel Sambuc   SmallVector<std::string, 2> Inputs;
120f4a2713aSLionel Sambuc 
121f4a2713aSLionel Sambuc private:
122f4a2713aSLionel Sambuc 
runImplclang::tooling::CompileJobAnalyzer123f4a2713aSLionel Sambuc   void runImpl(const driver::Action *A, bool Collect) {
124f4a2713aSLionel Sambuc     bool CollectChildren = Collect;
125f4a2713aSLionel Sambuc     switch (A->getKind()) {
126f4a2713aSLionel Sambuc     case driver::Action::CompileJobClass:
127f4a2713aSLionel Sambuc       CollectChildren = true;
128f4a2713aSLionel Sambuc       break;
129f4a2713aSLionel Sambuc 
130f4a2713aSLionel Sambuc     case driver::Action::InputClass: {
131f4a2713aSLionel Sambuc       if (Collect) {
132f4a2713aSLionel Sambuc         const driver::InputAction *IA = cast<driver::InputAction>(A);
133f4a2713aSLionel Sambuc         Inputs.push_back(IA->getInputArg().getSpelling());
134f4a2713aSLionel Sambuc       }
135f4a2713aSLionel Sambuc     } break;
136f4a2713aSLionel Sambuc 
137f4a2713aSLionel Sambuc     default:
138f4a2713aSLionel Sambuc       // Don't care about others
139f4a2713aSLionel Sambuc       ;
140f4a2713aSLionel Sambuc     }
141f4a2713aSLionel Sambuc 
142f4a2713aSLionel Sambuc     for (driver::ActionList::const_iterator I = A->begin(), E = A->end();
143f4a2713aSLionel Sambuc          I != E; ++I)
144f4a2713aSLionel Sambuc       runImpl(*I, CollectChildren);
145f4a2713aSLionel Sambuc   }
146f4a2713aSLionel Sambuc };
147f4a2713aSLionel Sambuc 
148f4a2713aSLionel Sambuc // Special DiagnosticConsumer that looks for warn_drv_input_file_unused
149f4a2713aSLionel Sambuc // diagnostics from the driver and collects the option strings for those unused
150f4a2713aSLionel Sambuc // options.
151f4a2713aSLionel Sambuc class UnusedInputDiagConsumer : public DiagnosticConsumer {
152f4a2713aSLionel Sambuc public:
UnusedInputDiagConsumer()153*0a6a1f1dSLionel Sambuc   UnusedInputDiagConsumer() : Other(nullptr) {}
154f4a2713aSLionel Sambuc 
155f4a2713aSLionel Sambuc   // Useful for debugging, chain diagnostics to another consumer after
156f4a2713aSLionel Sambuc   // recording for our own purposes.
UnusedInputDiagConsumer(DiagnosticConsumer * Other)157f4a2713aSLionel Sambuc   UnusedInputDiagConsumer(DiagnosticConsumer *Other) : Other(Other) {}
158f4a2713aSLionel Sambuc 
HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,const Diagnostic & Info)159f4a2713aSLionel Sambuc   virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
160*0a6a1f1dSLionel Sambuc                                 const Diagnostic &Info) override {
161f4a2713aSLionel Sambuc     if (Info.getID() == clang::diag::warn_drv_input_file_unused) {
162f4a2713aSLionel Sambuc       // Arg 1 for this diagnostic is the option that didn't get used.
163f4a2713aSLionel Sambuc       UnusedInputs.push_back(Info.getArgStdStr(0));
164f4a2713aSLionel Sambuc     }
165f4a2713aSLionel Sambuc     if (Other)
166f4a2713aSLionel Sambuc       Other->HandleDiagnostic(DiagLevel, Info);
167f4a2713aSLionel Sambuc   }
168f4a2713aSLionel Sambuc 
169f4a2713aSLionel Sambuc   DiagnosticConsumer *Other;
170f4a2713aSLionel Sambuc   SmallVector<std::string, 2> UnusedInputs;
171f4a2713aSLionel Sambuc };
172f4a2713aSLionel Sambuc 
173f4a2713aSLionel Sambuc // Unary functor for asking "Given a StringRef S1, does there exist a string
174f4a2713aSLionel Sambuc // S2 in Arr where S1 == S2?"
175f4a2713aSLionel Sambuc struct MatchesAny {
MatchesAnyclang::tooling::MatchesAny176f4a2713aSLionel Sambuc   MatchesAny(ArrayRef<std::string> Arr) : Arr(Arr) {}
operator ()clang::tooling::MatchesAny177f4a2713aSLionel Sambuc   bool operator() (StringRef S) {
178f4a2713aSLionel Sambuc     for (const std::string *I = Arr.begin(), *E = Arr.end(); I != E; ++I)
179f4a2713aSLionel Sambuc       if (*I == S)
180f4a2713aSLionel Sambuc         return true;
181f4a2713aSLionel Sambuc     return false;
182f4a2713aSLionel Sambuc   }
183f4a2713aSLionel Sambuc private:
184f4a2713aSLionel Sambuc   ArrayRef<std::string> Arr;
185f4a2713aSLionel Sambuc };
186f4a2713aSLionel Sambuc 
187f4a2713aSLionel Sambuc /// \brief Strips any positional args and possible argv[0] from a command-line
188f4a2713aSLionel Sambuc /// provided by the user to construct a FixedCompilationDatabase.
189f4a2713aSLionel Sambuc ///
190f4a2713aSLionel Sambuc /// FixedCompilationDatabase requires a command line to be in this format as it
191f4a2713aSLionel Sambuc /// constructs the command line for each file by appending the name of the file
192f4a2713aSLionel Sambuc /// to be compiled. FixedCompilationDatabase also adds its own argv[0] to the
193f4a2713aSLionel Sambuc /// start of the command line although its value is not important as it's just
194f4a2713aSLionel Sambuc /// ignored by the Driver invoked by the ClangTool using the
195f4a2713aSLionel Sambuc /// FixedCompilationDatabase.
196f4a2713aSLionel Sambuc ///
197f4a2713aSLionel Sambuc /// FIXME: This functionality should probably be made available by
198f4a2713aSLionel Sambuc /// clang::driver::Driver although what the interface should look like is not
199f4a2713aSLionel Sambuc /// clear.
200f4a2713aSLionel Sambuc ///
201f4a2713aSLionel Sambuc /// \param[in] Args Args as provided by the user.
202f4a2713aSLionel Sambuc /// \return Resulting stripped command line.
203f4a2713aSLionel Sambuc ///          \li true if successful.
204f4a2713aSLionel Sambuc ///          \li false if \c Args cannot be used for compilation jobs (e.g.
205f4a2713aSLionel Sambuc ///          contains an option like -E or -version).
stripPositionalArgs(std::vector<const char * > Args,std::vector<std::string> & Result)206*0a6a1f1dSLionel Sambuc static bool stripPositionalArgs(std::vector<const char *> Args,
207f4a2713aSLionel Sambuc                                 std::vector<std::string> &Result) {
208f4a2713aSLionel Sambuc   IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
209f4a2713aSLionel Sambuc   UnusedInputDiagConsumer DiagClient;
210f4a2713aSLionel Sambuc   DiagnosticsEngine Diagnostics(
211f4a2713aSLionel Sambuc       IntrusiveRefCntPtr<clang::DiagnosticIDs>(new DiagnosticIDs()),
212f4a2713aSLionel Sambuc       &*DiagOpts, &DiagClient, false);
213f4a2713aSLionel Sambuc 
214*0a6a1f1dSLionel Sambuc   // The clang executable path isn't required since the jobs the driver builds
215*0a6a1f1dSLionel Sambuc   // will not be executed.
216*0a6a1f1dSLionel Sambuc   std::unique_ptr<driver::Driver> NewDriver(new driver::Driver(
217f4a2713aSLionel Sambuc       /* ClangExecutable= */ "", llvm::sys::getDefaultTargetTriple(),
218*0a6a1f1dSLionel Sambuc       Diagnostics));
219f4a2713aSLionel Sambuc   NewDriver->setCheckInputsExist(false);
220f4a2713aSLionel Sambuc 
221f4a2713aSLionel Sambuc   // This becomes the new argv[0]. The value is actually not important as it
222f4a2713aSLionel Sambuc   // isn't used for invoking Tools.
223f4a2713aSLionel Sambuc   Args.insert(Args.begin(), "clang-tool");
224f4a2713aSLionel Sambuc 
225f4a2713aSLionel Sambuc   // By adding -c, we force the driver to treat compilation as the last phase.
226f4a2713aSLionel Sambuc   // It will then issue warnings via Diagnostics about un-used options that
227f4a2713aSLionel Sambuc   // would have been used for linking. If the user provided a compiler name as
228f4a2713aSLionel Sambuc   // the original argv[0], this will be treated as a linker input thanks to
229f4a2713aSLionel Sambuc   // insertng a new argv[0] above. All un-used options get collected by
230f4a2713aSLionel Sambuc   // UnusedInputdiagConsumer and get stripped out later.
231f4a2713aSLionel Sambuc   Args.push_back("-c");
232f4a2713aSLionel Sambuc 
233f4a2713aSLionel Sambuc   // Put a dummy C++ file on to ensure there's at least one compile job for the
234f4a2713aSLionel Sambuc   // driver to construct. If the user specified some other argument that
235f4a2713aSLionel Sambuc   // prevents compilation, e.g. -E or something like -version, we may still end
236f4a2713aSLionel Sambuc   // up with no jobs but then this is the user's fault.
237f4a2713aSLionel Sambuc   Args.push_back("placeholder.cpp");
238f4a2713aSLionel Sambuc 
239*0a6a1f1dSLionel Sambuc   // Remove -no-integrated-as; it's not used for syntax checking,
240*0a6a1f1dSLionel Sambuc   // and it confuses targets which don't support this option.
241*0a6a1f1dSLionel Sambuc   Args.erase(std::remove_if(Args.begin(), Args.end(),
242*0a6a1f1dSLionel Sambuc                             MatchesAny(std::string("-no-integrated-as"))),
243*0a6a1f1dSLionel Sambuc              Args.end());
244*0a6a1f1dSLionel Sambuc 
245*0a6a1f1dSLionel Sambuc   const std::unique_ptr<driver::Compilation> Compilation(
246f4a2713aSLionel Sambuc       NewDriver->BuildCompilation(Args));
247f4a2713aSLionel Sambuc 
248f4a2713aSLionel Sambuc   const driver::JobList &Jobs = Compilation->getJobs();
249f4a2713aSLionel Sambuc 
250f4a2713aSLionel Sambuc   CompileJobAnalyzer CompileAnalyzer;
251f4a2713aSLionel Sambuc 
252*0a6a1f1dSLionel Sambuc   for (const auto &Job : Jobs) {
253*0a6a1f1dSLionel Sambuc     if (Job.getKind() == driver::Job::CommandClass) {
254*0a6a1f1dSLionel Sambuc       const driver::Command &Cmd = cast<driver::Command>(Job);
255f4a2713aSLionel Sambuc       // Collect only for Assemble jobs. If we do all jobs we get duplicates
256f4a2713aSLionel Sambuc       // since Link jobs point to Assemble jobs as inputs.
257*0a6a1f1dSLionel Sambuc       if (Cmd.getSource().getKind() == driver::Action::AssembleJobClass)
258*0a6a1f1dSLionel Sambuc         CompileAnalyzer.run(&Cmd.getSource());
259f4a2713aSLionel Sambuc     }
260f4a2713aSLionel Sambuc   }
261f4a2713aSLionel Sambuc 
262f4a2713aSLionel Sambuc   if (CompileAnalyzer.Inputs.empty()) {
263f4a2713aSLionel Sambuc     // No compile jobs found.
264f4a2713aSLionel Sambuc     // FIXME: Emit a warning of some kind?
265f4a2713aSLionel Sambuc     return false;
266f4a2713aSLionel Sambuc   }
267f4a2713aSLionel Sambuc 
268f4a2713aSLionel Sambuc   // Remove all compilation input files from the command line. This is
269f4a2713aSLionel Sambuc   // necessary so that getCompileCommands() can construct a command line for
270f4a2713aSLionel Sambuc   // each file.
271f4a2713aSLionel Sambuc   std::vector<const char *>::iterator End = std::remove_if(
272f4a2713aSLionel Sambuc       Args.begin(), Args.end(), MatchesAny(CompileAnalyzer.Inputs));
273f4a2713aSLionel Sambuc 
274f4a2713aSLionel Sambuc   // Remove all inputs deemed unused for compilation.
275f4a2713aSLionel Sambuc   End = std::remove_if(Args.begin(), End, MatchesAny(DiagClient.UnusedInputs));
276f4a2713aSLionel Sambuc 
277f4a2713aSLionel Sambuc   // Remove the -c add above as well. It will be at the end right now.
278*0a6a1f1dSLionel Sambuc   assert(strcmp(*(End - 1), "-c") == 0);
279f4a2713aSLionel Sambuc   --End;
280f4a2713aSLionel Sambuc 
281f4a2713aSLionel Sambuc   Result = std::vector<std::string>(Args.begin() + 1, End);
282f4a2713aSLionel Sambuc   return true;
283f4a2713aSLionel Sambuc }
284f4a2713aSLionel Sambuc 
285f4a2713aSLionel Sambuc FixedCompilationDatabase *
loadFromCommandLine(int & Argc,const char ** Argv,Twine Directory)286f4a2713aSLionel Sambuc FixedCompilationDatabase::loadFromCommandLine(int &Argc,
287f4a2713aSLionel Sambuc                                               const char **Argv,
288f4a2713aSLionel Sambuc                                               Twine Directory) {
289f4a2713aSLionel Sambuc   const char **DoubleDash = std::find(Argv, Argv + Argc, StringRef("--"));
290f4a2713aSLionel Sambuc   if (DoubleDash == Argv + Argc)
291*0a6a1f1dSLionel Sambuc     return nullptr;
292f4a2713aSLionel Sambuc   std::vector<const char *> CommandLine(DoubleDash + 1, Argv + Argc);
293f4a2713aSLionel Sambuc   Argc = DoubleDash - Argv;
294f4a2713aSLionel Sambuc 
295f4a2713aSLionel Sambuc   std::vector<std::string> StrippedArgs;
296f4a2713aSLionel Sambuc   if (!stripPositionalArgs(CommandLine, StrippedArgs))
297*0a6a1f1dSLionel Sambuc     return nullptr;
298f4a2713aSLionel Sambuc   return new FixedCompilationDatabase(Directory, StrippedArgs);
299f4a2713aSLionel Sambuc }
300f4a2713aSLionel Sambuc 
301f4a2713aSLionel Sambuc FixedCompilationDatabase::
FixedCompilationDatabase(Twine Directory,ArrayRef<std::string> CommandLine)302f4a2713aSLionel Sambuc FixedCompilationDatabase(Twine Directory, ArrayRef<std::string> CommandLine) {
303f4a2713aSLionel Sambuc   std::vector<std::string> ToolCommandLine(1, "clang-tool");
304f4a2713aSLionel Sambuc   ToolCommandLine.insert(ToolCommandLine.end(),
305f4a2713aSLionel Sambuc                          CommandLine.begin(), CommandLine.end());
306*0a6a1f1dSLionel Sambuc   CompileCommands.push_back(
307*0a6a1f1dSLionel Sambuc       CompileCommand(Directory, std::move(ToolCommandLine)));
308f4a2713aSLionel Sambuc }
309f4a2713aSLionel Sambuc 
310f4a2713aSLionel Sambuc std::vector<CompileCommand>
getCompileCommands(StringRef FilePath) const311f4a2713aSLionel Sambuc FixedCompilationDatabase::getCompileCommands(StringRef FilePath) const {
312f4a2713aSLionel Sambuc   std::vector<CompileCommand> Result(CompileCommands);
313f4a2713aSLionel Sambuc   Result[0].CommandLine.push_back(FilePath);
314f4a2713aSLionel Sambuc   return Result;
315f4a2713aSLionel Sambuc }
316f4a2713aSLionel Sambuc 
317f4a2713aSLionel Sambuc std::vector<std::string>
getAllFiles() const318f4a2713aSLionel Sambuc FixedCompilationDatabase::getAllFiles() const {
319f4a2713aSLionel Sambuc   return std::vector<std::string>();
320f4a2713aSLionel Sambuc }
321f4a2713aSLionel Sambuc 
322f4a2713aSLionel Sambuc std::vector<CompileCommand>
getAllCompileCommands() const323f4a2713aSLionel Sambuc FixedCompilationDatabase::getAllCompileCommands() const {
324f4a2713aSLionel Sambuc   return std::vector<CompileCommand>();
325f4a2713aSLionel Sambuc }
326f4a2713aSLionel Sambuc 
327f4a2713aSLionel Sambuc // This anchor is used to force the linker to link in the generated object file
328f4a2713aSLionel Sambuc // and thus register the JSONCompilationDatabasePlugin.
329f4a2713aSLionel Sambuc extern volatile int JSONAnchorSource;
330f4a2713aSLionel Sambuc static int JSONAnchorDest = JSONAnchorSource;
331f4a2713aSLionel Sambuc 
332f4a2713aSLionel Sambuc } // end namespace tooling
333f4a2713aSLionel Sambuc } // end namespace clang
334