[libclang] add CompilationDatabase support

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@159484 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/tools/libclang/CIndexCompilationDB.cpp b/tools/libclang/CIndexCompilationDB.cpp
new file mode 100644
index 0000000..a537c9d
--- /dev/null
+++ b/tools/libclang/CIndexCompilationDB.cpp
@@ -0,0 +1,130 @@
+#include "clang-c/CXCompilationDatabase.h"
+#include "clang/Tooling/CompilationDatabase.h"
+#include "CXString.h"
+
+using namespace clang;
+using namespace clang::tooling;
+using namespace clang::cxstring;
+
+extern "C" {
+
+// FIXME: do something more usefull with the error message
+CXCompilationDatabase
+clang_tooling_CompilationDatabase_fromDirectory(
+  const char *BuildDir,
+  CXCompilationDatabase_Error *ErrorCode)
+{
+  std::string ErrorMsg;
+  CXCompilationDatabase_Error Err = CXCompilationDatabase_NoError;
+
+  CompilationDatabase *db = CompilationDatabase::loadFromDirectory(BuildDir,
+                                                                   ErrorMsg);
+
+  if (!db) {
+    fprintf(stderr, "LIBCLANG TOOLING ERROR: %s\n", ErrorMsg.c_str());
+    Err = CXCompilationDatabase_CanNotLoadDatabase;
+  }
+
+  if (ErrorCode)
+    *ErrorCode = Err;
+
+  return db;
+}
+
+void
+clang_tooling_CompilationDatabase_dispose(CXCompilationDatabase CDb)
+{
+  delete static_cast<CompilationDatabase *>(CDb);
+}
+
+struct AllocatedCXCompileCommands
+{
+  std::vector<CompileCommand> CCmd;
+
+  AllocatedCXCompileCommands(const std::vector<CompileCommand>& Cmd)
+    : CCmd(Cmd)
+  { }
+};
+
+CXCompileCommands
+clang_tooling_CompilationDatabase_getCompileCommands(CXCompilationDatabase CDb,
+                                 const char *CompleteFileName)
+{
+  if (CompilationDatabase *db = static_cast<CompilationDatabase *>(CDb)) {
+    const std::vector<CompileCommand>
+      CCmd(db->getCompileCommands(CompleteFileName));
+    if (!CCmd.empty())
+      return new AllocatedCXCompileCommands( CCmd );
+  }
+
+  return 0;
+}
+
+void
+clang_tooling_CompileCommands_dispose(CXCompileCommands Cmds)
+{
+  delete static_cast<AllocatedCXCompileCommands *>(Cmds);
+}
+
+unsigned
+clang_tooling_CompileCommands_getSize(CXCompileCommands Cmds)
+{
+  if (!Cmds)
+    return 0;
+
+  AllocatedCXCompileCommands *ACC =
+    static_cast<AllocatedCXCompileCommands *>(Cmds);
+
+  return ACC->CCmd.size();
+}
+
+CXCompileCommand
+clang_tooling_CompileCommands_getCommand(CXCompileCommands Cmds, unsigned I)
+{
+  if (!Cmds)
+    return 0;
+
+  AllocatedCXCompileCommands *ACC =
+    static_cast<AllocatedCXCompileCommands *>(Cmds);
+
+  if (I >= ACC->CCmd.size())
+    return 0;
+
+  return &ACC->CCmd[I];
+}
+
+CXString
+clang_tooling_CompileCommand_getDirectory(CXCompileCommand CCmd)
+{
+  if (!CCmd)
+    return createCXString((const char*)NULL);
+
+  CompileCommand *cmd = static_cast<CompileCommand *>(CCmd);
+  return createCXString(cmd->Directory);
+}
+
+unsigned
+clang_tooling_CompileCommand_getNumArgs(CXCompileCommand CCmd)
+{
+  if (!CCmd)
+    return 0;
+
+  return static_cast<CompileCommand *>(CCmd)->CommandLine.size();
+}
+
+CXString
+clang_tooling_CompileCommand_getArg(CXCompileCommand CCmd, unsigned Arg)
+{
+  if (!CCmd)
+    return createCXString((const char*)NULL);
+
+  CompileCommand *Cmd = static_cast<CompileCommand *>(CCmd);
+
+  if (Arg >= Cmd->CommandLine.size())
+    return createCXString((const char*)NULL);
+
+  return createCXString(Cmd->CommandLine[Arg]);
+}
+
+
+} // end: extern "C"
diff --git a/tools/libclang/CMakeLists.txt b/tools/libclang/CMakeLists.txt
index a1090fb..ee401ed 100644
--- a/tools/libclang/CMakeLists.txt
+++ b/tools/libclang/CMakeLists.txt
@@ -8,6 +8,7 @@
   CIndex.cpp
   CIndexCXX.cpp
   CIndexCodeCompletion.cpp
+  CIndexCompilationDB.cpp
   CIndexDiagnostic.cpp
   CIndexDiagnostic.h
   CIndexHigh.cpp
@@ -47,6 +48,7 @@
   clangEdit
   clangAST
   clangLex
+  clangTooling
   clangBasic
   )
 
diff --git a/tools/libclang/libclang.exports b/tools/libclang/libclang.exports
index c28b3b4..bba883f 100644
--- a/tools/libclang/libclang.exports
+++ b/tools/libclang/libclang.exports
@@ -204,5 +204,14 @@
 clang_sortCodeCompletionResults
 clang_toggleCrashRecovery
 clang_tokenize
+clang_tooling_CompilationDatabase_fromDirectory
+clang_tooling_CompilationDatabase_dispose
+clang_tooling_CompilationDatabase_getCompileCommands
+clang_tooling_CompileCommands_dispose
+clang_tooling_CompileCommands_getSize
+clang_tooling_CompileCommands_getCommand
+clang_tooling_CompileCommand_getDirectory
+clang_tooling_CompileCommand_getNumArgs
+clang_tooling_CompileCommand_getArg
 clang_visitChildren
 clang_visitChildrenWithBlock