CompilationDatabase.cpp revision 55fc873017f10f6f566b182b70f6fc22aefa3464
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 23namespace clang { 24namespace tooling { 25 26CompilationDatabase::~CompilationDatabase() {} 27 28CompilationDatabase * 29CompilationDatabase::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 48static CompilationDatabase * 49findCompilationDatabaseFromDirectory(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 72CompilationDatabase * 73CompilationDatabase::autoDetectFromSource(StringRef SourceFile, 74 std::string &ErrorMessage) { 75 llvm::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 87CompilationDatabase * 88CompilationDatabase::autoDetectFromDirectory(StringRef SourceDir, 89 std::string &ErrorMessage) { 90 llvm::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 101CompilationDatabasePlugin::~CompilationDatabasePlugin() {} 102 103FixedCompilationDatabase * 104FixedCompilationDatabase::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 115FixedCompilationDatabase:: 116FixedCompilationDatabase(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 123std::vector<CompileCommand> 124FixedCompilationDatabase::getCompileCommands(StringRef FilePath) const { 125 std::vector<CompileCommand> Result(CompileCommands); 126 Result[0].CommandLine.push_back(FilePath); 127 return Result; 128} 129 130std::vector<std::string> 131FixedCompilationDatabase::getAllFiles() const { 132 return std::vector<std::string>(); 133} 134 135std::vector<CompileCommand> 136FixedCompilationDatabase::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. 142extern volatile int JSONAnchorSource; 143static int JSONAnchorDest = JSONAnchorSource; 144 145} // end namespace tooling 146} // end namespace clang 147