1 //===--- CompilationDatabase.cpp - ----------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file contains implementations of the CompilationDatabase base class
11 // and the FixedCompilationDatabase.
13 //===----------------------------------------------------------------------===//
15 #include "clang/Tooling/CompilationDatabase.h"
16 #include "clang/Tooling/CompilationDatabasePluginRegistry.h"
17 #include "clang/Tooling/Tooling.h"
18 #include "llvm/ADT/SmallString.h"
19 #include "llvm/Support/Path.h"
20 #include "llvm/Support/system_error.h"
26 CompilationDatabase::~CompilationDatabase() {}
29 CompilationDatabase::loadFromDirectory(StringRef BuildDirectory,
30 std::string &ErrorMessage) {
31 std::stringstream ErrorStream;
32 for (CompilationDatabasePluginRegistry::iterator
33 It = CompilationDatabasePluginRegistry::begin(),
34 Ie = CompilationDatabasePluginRegistry::end();
36 std::string DatabaseErrorMessage;
37 OwningPtr<CompilationDatabasePlugin> Plugin(It->instantiate());
38 if (CompilationDatabase *DB =
39 Plugin->loadFromDirectory(BuildDirectory, DatabaseErrorMessage))
42 ErrorStream << It->getName() << ": " << DatabaseErrorMessage << "\n";
44 ErrorMessage = ErrorStream.str();
48 static CompilationDatabase *
49 findCompilationDatabaseFromDirectory(StringRef Directory,
50 std::string &ErrorMessage) {
51 std::stringstream ErrorStream;
52 bool HasErrorMessage = false;
53 while (!Directory.empty()) {
54 std::string LoadErrorMessage;
56 if (CompilationDatabase *DB =
57 CompilationDatabase::loadFromDirectory(Directory, LoadErrorMessage))
60 if (!HasErrorMessage) {
61 ErrorStream << "No compilation database found in " << Directory.str()
62 << " or any parent directory\n" << LoadErrorMessage;
63 HasErrorMessage = true;
66 Directory = llvm::sys::path::parent_path(Directory);
68 ErrorMessage = ErrorStream.str();
73 CompilationDatabase::autoDetectFromSource(StringRef SourceFile,
74 std::string &ErrorMessage) {
75 SmallString<1024> AbsolutePath(getAbsolutePath(SourceFile));
76 StringRef Directory = llvm::sys::path::parent_path(AbsolutePath);
78 CompilationDatabase *DB = findCompilationDatabaseFromDirectory(Directory,
82 ErrorMessage = ("Could not auto-detect compilation database for file \"" +
83 SourceFile + "\"\n" + ErrorMessage).str();
88 CompilationDatabase::autoDetectFromDirectory(StringRef SourceDir,
89 std::string &ErrorMessage) {
90 SmallString<1024> AbsolutePath(getAbsolutePath(SourceDir));
92 CompilationDatabase *DB = findCompilationDatabaseFromDirectory(AbsolutePath,
96 ErrorMessage = ("Could not auto-detect compilation database from directory \"" +
97 SourceDir + "\"\n" + ErrorMessage).str();
101 CompilationDatabasePlugin::~CompilationDatabasePlugin() {}
103 FixedCompilationDatabase *
104 FixedCompilationDatabase::loadFromCommandLine(int &Argc,
107 const char **DoubleDash = std::find(Argv, Argv + Argc, StringRef("--"));
108 if (DoubleDash == Argv + Argc)
110 std::vector<std::string> CommandLine(DoubleDash + 1, Argv + Argc);
111 Argc = DoubleDash - Argv;
112 return new FixedCompilationDatabase(Directory, CommandLine);
115 FixedCompilationDatabase::
116 FixedCompilationDatabase(Twine Directory, ArrayRef<std::string> CommandLine) {
117 std::vector<std::string> ToolCommandLine(1, "clang-tool");
118 ToolCommandLine.insert(ToolCommandLine.end(),
119 CommandLine.begin(), CommandLine.end());
120 CompileCommands.push_back(CompileCommand(Directory, ToolCommandLine));
123 std::vector<CompileCommand>
124 FixedCompilationDatabase::getCompileCommands(StringRef FilePath) const {
125 std::vector<CompileCommand> Result(CompileCommands);
126 Result[0].CommandLine.push_back(FilePath);
130 std::vector<std::string>
131 FixedCompilationDatabase::getAllFiles() const {
132 return std::vector<std::string>();
135 std::vector<CompileCommand>
136 FixedCompilationDatabase::getAllCompileCommands() const {
137 return std::vector<CompileCommand>();
140 // This anchor is used to force the linker to link in the generated object file
141 // and thus register the JSONCompilationDatabasePlugin.
142 extern volatile int JSONAnchorSource;
143 static int JSONAnchorDest = JSONAnchorSource;
145 } // end namespace tooling
146 } // end namespace clang