blob: 6e941802dc2a2a8f392a474f74e92822d79d1556 [file] [log] [blame]
Manuel Klimekcb971c62012-04-04 12:07:46 +00001//===--- CompilationDatabase.cpp - ----------------------------------------===//
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//
Daniel Jasper7fd90b02012-08-24 05:50:27 +000010// This file contains implementations of the CompilationDatabase base class
11// and the FixedCompilationDatabase.
Manuel Klimekcb971c62012-04-04 12:07:46 +000012//
13//===----------------------------------------------------------------------===//
14
Daniel Jasper7fd90b02012-08-24 05:50:27 +000015#include <sstream>
Manuel Klimekcb971c62012-04-04 12:07:46 +000016#include "clang/Tooling/CompilationDatabase.h"
Daniel Jasper7fd90b02012-08-24 05:50:27 +000017#include "clang/Tooling/CompilationDatabasePluginRegistry.h"
Manuel Klimek8fa2fb82012-07-10 13:10:51 +000018#include "clang/Tooling/Tooling.h"
Manuel Klimekcb971c62012-04-04 12:07:46 +000019#include "llvm/ADT/SmallString.h"
Manuel Klimekcb971c62012-04-04 12:07:46 +000020#include "llvm/Support/Path.h"
21#include "llvm/Support/system_error.h"
22
23namespace clang {
24namespace tooling {
25
Manuel Klimekcb971c62012-04-04 12:07:46 +000026CompilationDatabase::~CompilationDatabase() {}
27
28CompilationDatabase *
29CompilationDatabase::loadFromDirectory(StringRef BuildDirectory,
30 std::string &ErrorMessage) {
Daniel Jasper7fd90b02012-08-24 05:50:27 +000031 std::stringstream ErrorStream;
32 for (CompilationDatabasePluginRegistry::iterator
33 It = CompilationDatabasePluginRegistry::begin(),
34 Ie = CompilationDatabasePluginRegistry::end();
35 It != Ie; ++It) {
36 std::string DatabaseErrorMessage;
37 OwningPtr<CompilationDatabasePlugin> Plugin(It->instantiate());
38 if (CompilationDatabase *DB =
39 Plugin->loadFromDirectory(BuildDirectory, DatabaseErrorMessage))
40 return DB;
41 else
42 ErrorStream << It->getName() << ": " << DatabaseErrorMessage << "\n";
Manuel Klimekcb971c62012-04-04 12:07:46 +000043 }
Daniel Jasper7fd90b02012-08-24 05:50:27 +000044 ErrorMessage = ErrorStream.str();
45 return NULL;
Manuel Klimekcb971c62012-04-04 12:07:46 +000046}
47
Arnaud A. de Grandmaison4187df52012-07-10 16:56:35 +000048static CompilationDatabase *
Daniel Jasper7fd90b02012-08-24 05:50:27 +000049findCompilationDatabaseFromDirectory(StringRef Directory,
50 std::string &ErrorMessage) {
51 std::stringstream ErrorStream;
Arnaud A. de Grandmaison4187df52012-07-10 16:56:35 +000052 while (!Directory.empty()) {
53 std::string LoadErrorMessage;
54
55 if (CompilationDatabase *DB =
56 CompilationDatabase::loadFromDirectory(Directory, LoadErrorMessage))
57 return DB;
Daniel Jasper7fd90b02012-08-24 05:50:27 +000058 ErrorStream << "No compilation database found in " << Directory.str()
59 << "\n" << LoadErrorMessage;
Arnaud A. de Grandmaison4187df52012-07-10 16:56:35 +000060
61 Directory = llvm::sys::path::parent_path(Directory);
62 }
Daniel Jasper7fd90b02012-08-24 05:50:27 +000063 ErrorMessage = ErrorStream.str();
Arnaud A. de Grandmaison4187df52012-07-10 16:56:35 +000064 return NULL;
65}
66
Manuel Klimek8fa2fb82012-07-10 13:10:51 +000067CompilationDatabase *
68CompilationDatabase::autoDetectFromSource(StringRef SourceFile,
69 std::string &ErrorMessage) {
70 llvm::SmallString<1024> AbsolutePath(getAbsolutePath(SourceFile));
71 StringRef Directory = llvm::sys::path::parent_path(AbsolutePath);
Arnaud A. de Grandmaison4187df52012-07-10 16:56:35 +000072
Daniel Jasper7fd90b02012-08-24 05:50:27 +000073 CompilationDatabase *DB = findCompilationDatabaseFromDirectory(Directory,
74 ErrorMessage);
Arnaud A. de Grandmaison4187df52012-07-10 16:56:35 +000075
76 if (!DB)
77 ErrorMessage = ("Could not auto-detect compilation database for file \"" +
Daniel Jasper7fd90b02012-08-24 05:50:27 +000078 SourceFile + "\"\n" + ErrorMessage).str();
Arnaud A. de Grandmaison4187df52012-07-10 16:56:35 +000079 return DB;
80}
81
82CompilationDatabase *
83CompilationDatabase::autoDetectFromDirectory(StringRef SourceDir,
84 std::string &ErrorMessage) {
85 llvm::SmallString<1024> AbsolutePath(getAbsolutePath(SourceDir));
86
Daniel Jasper7fd90b02012-08-24 05:50:27 +000087 CompilationDatabase *DB = findCompilationDatabaseFromDirectory(AbsolutePath,
88 ErrorMessage);
Arnaud A. de Grandmaison4187df52012-07-10 16:56:35 +000089
90 if (!DB)
91 ErrorMessage = ("Could not auto-detect compilation database from directory \"" +
Daniel Jasper7fd90b02012-08-24 05:50:27 +000092 SourceDir + "\"\n" + ErrorMessage).str();
Arnaud A. de Grandmaison4187df52012-07-10 16:56:35 +000093 return DB;
Manuel Klimek8fa2fb82012-07-10 13:10:51 +000094}
95
Daniel Jasper7fd90b02012-08-24 05:50:27 +000096CompilationDatabasePlugin::~CompilationDatabasePlugin() {}
97
Manuel Klimek30318e62012-04-18 07:41:50 +000098FixedCompilationDatabase *
99FixedCompilationDatabase::loadFromCommandLine(int &Argc,
100 const char **Argv,
101 Twine Directory) {
102 const char **DoubleDash = std::find(Argv, Argv + Argc, StringRef("--"));
103 if (DoubleDash == Argv + Argc)
104 return NULL;
105 std::vector<std::string> CommandLine(DoubleDash + 1, Argv + Argc);
106 Argc = DoubleDash - Argv;
107 return new FixedCompilationDatabase(Directory, CommandLine);
108}
109
110FixedCompilationDatabase::
111FixedCompilationDatabase(Twine Directory, ArrayRef<std::string> CommandLine) {
112 std::vector<std::string> ToolCommandLine(1, "clang-tool");
113 ToolCommandLine.insert(ToolCommandLine.end(),
114 CommandLine.begin(), CommandLine.end());
115 CompileCommands.push_back(CompileCommand(Directory, ToolCommandLine));
116}
117
118std::vector<CompileCommand>
119FixedCompilationDatabase::getCompileCommands(StringRef FilePath) const {
120 std::vector<CompileCommand> Result(CompileCommands);
121 Result[0].CommandLine.push_back(FilePath);
122 return Result;
123}
124
Manuel Klimeka3c70962012-07-13 12:31:45 +0000125std::vector<std::string>
126FixedCompilationDatabase::getAllFiles() const {
127 return std::vector<std::string>();
128}
129
Daniel Jasper7fd90b02012-08-24 05:50:27 +0000130// This anchor is used to force the linker to link in the generated object file
131// and thus register the JSONCompilationDatabasePlugin.
132extern volatile int JSONAnchorSource;
133static int JSONAnchorDest = JSONAnchorSource;
Manuel Klimekcb971c62012-04-04 12:07:46 +0000134
135} // end namespace tooling
136} // end namespace clang