]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/llvm/tools/clang/lib/Tooling/CompilationDatabase.cpp
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / llvm / tools / clang / lib / Tooling / CompilationDatabase.cpp
1 //===--- 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 //
10 //  This file contains implementations of the CompilationDatabase base class
11 //  and the FixedCompilationDatabase.
12 //
13 //===----------------------------------------------------------------------===//
14
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"
21 #include <sstream>
22
23 namespace clang {
24 namespace tooling {
25
26 CompilationDatabase::~CompilationDatabase() {}
27
28 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();
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";
43   }
44   ErrorMessage = ErrorStream.str();
45   return NULL;
46 }
47
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;
55
56     if (CompilationDatabase *DB =
57            CompilationDatabase::loadFromDirectory(Directory, LoadErrorMessage))
58       return DB;
59
60     if (!HasErrorMessage) {
61       ErrorStream << "No compilation database found in " << Directory.str()
62                   << " or any parent directory\n" << LoadErrorMessage;
63       HasErrorMessage = true;
64     }
65
66     Directory = llvm::sys::path::parent_path(Directory);
67   }
68   ErrorMessage = ErrorStream.str();
69   return NULL;
70 }
71
72 CompilationDatabase *
73 CompilationDatabase::autoDetectFromSource(StringRef SourceFile,
74                                           std::string &ErrorMessage) {
75   SmallString<1024> AbsolutePath(getAbsolutePath(SourceFile));
76   StringRef Directory = llvm::sys::path::parent_path(AbsolutePath);
77
78   CompilationDatabase *DB = findCompilationDatabaseFromDirectory(Directory,
79                                                                  ErrorMessage);
80
81   if (!DB)
82     ErrorMessage = ("Could not auto-detect compilation database for file \"" +
83                    SourceFile + "\"\n" + ErrorMessage).str();
84   return DB;
85 }
86
87 CompilationDatabase *
88 CompilationDatabase::autoDetectFromDirectory(StringRef SourceDir,
89                                              std::string &ErrorMessage) {
90   SmallString<1024> AbsolutePath(getAbsolutePath(SourceDir));
91
92   CompilationDatabase *DB = findCompilationDatabaseFromDirectory(AbsolutePath,
93                                                                  ErrorMessage);
94
95   if (!DB)
96     ErrorMessage = ("Could not auto-detect compilation database from directory \"" +
97                    SourceDir + "\"\n" + ErrorMessage).str();
98   return DB;
99 }
100
101 CompilationDatabasePlugin::~CompilationDatabasePlugin() {}
102
103 FixedCompilationDatabase *
104 FixedCompilationDatabase::loadFromCommandLine(int &Argc,
105                                               const char **Argv,
106                                               Twine Directory) {
107   const char **DoubleDash = std::find(Argv, Argv + Argc, StringRef("--"));
108   if (DoubleDash == Argv + Argc)
109     return NULL;
110   std::vector<std::string> CommandLine(DoubleDash + 1, Argv + Argc);
111   Argc = DoubleDash - Argv;
112   return new FixedCompilationDatabase(Directory, CommandLine);
113 }
114
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));
121 }
122
123 std::vector<CompileCommand>
124 FixedCompilationDatabase::getCompileCommands(StringRef FilePath) const {
125   std::vector<CompileCommand> Result(CompileCommands);
126   Result[0].CommandLine.push_back(FilePath);
127   return Result;
128 }
129
130 std::vector<std::string>
131 FixedCompilationDatabase::getAllFiles() const {
132   return std::vector<std::string>();
133 }
134
135 std::vector<CompileCommand>
136 FixedCompilationDatabase::getAllCompileCommands() const {
137   return std::vector<CompileCommand>();
138 }
139
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;
144
145 } // end namespace tooling
146 } // end namespace clang