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