1#include "clang-c/CXCompilationDatabase.h"
2#include "CXString.h"
3#include "clang/Tooling/CompilationDatabase.h"
4#include <cstdio>
5
6using namespace clang;
7using namespace clang::tooling;
8
9// FIXME: do something more useful with the error message
10CXCompilationDatabase
11clang_CompilationDatabase_fromDirectory(const char *BuildDir,
12                                        CXCompilationDatabase_Error *ErrorCode)
13{
14  std::string ErrorMsg;
15  CXCompilationDatabase_Error Err = CXCompilationDatabase_NoError;
16
17  std::unique_ptr<CompilationDatabase> db =
18      CompilationDatabase::loadFromDirectory(BuildDir, ErrorMsg);
19
20  if (!db) {
21    fprintf(stderr, "LIBCLANG TOOLING ERROR: %s\n", ErrorMsg.c_str());
22    Err = CXCompilationDatabase_CanNotLoadDatabase;
23  }
24
25  if (ErrorCode)
26    *ErrorCode = Err;
27
28  return db.release();
29}
30
31void
32clang_CompilationDatabase_dispose(CXCompilationDatabase CDb)
33{
34  delete static_cast<CompilationDatabase *>(CDb);
35}
36
37struct AllocatedCXCompileCommands
38{
39  std::vector<CompileCommand> CCmd;
40
41  AllocatedCXCompileCommands(std::vector<CompileCommand> Cmd)
42      : CCmd(std::move(Cmd)) {}
43};
44
45CXCompileCommands
46clang_CompilationDatabase_getCompileCommands(CXCompilationDatabase CDb,
47                                             const char *CompleteFileName)
48{
49  if (CompilationDatabase *db = static_cast<CompilationDatabase *>(CDb)) {
50    std::vector<CompileCommand> CCmd(db->getCompileCommands(CompleteFileName));
51    if (!CCmd.empty())
52      return new AllocatedCXCompileCommands(std::move(CCmd));
53  }
54
55  return nullptr;
56}
57
58CXCompileCommands
59clang_CompilationDatabase_getAllCompileCommands(CXCompilationDatabase CDb) {
60  if (CompilationDatabase *db = static_cast<CompilationDatabase *>(CDb)) {
61    std::vector<CompileCommand> CCmd(db->getAllCompileCommands());
62    if (!CCmd.empty())
63      return new AllocatedCXCompileCommands(std::move(CCmd));
64  }
65
66  return nullptr;
67}
68
69void
70clang_CompileCommands_dispose(CXCompileCommands Cmds)
71{
72  delete static_cast<AllocatedCXCompileCommands *>(Cmds);
73}
74
75unsigned
76clang_CompileCommands_getSize(CXCompileCommands Cmds)
77{
78  if (!Cmds)
79    return 0;
80
81  AllocatedCXCompileCommands *ACC =
82    static_cast<AllocatedCXCompileCommands *>(Cmds);
83
84  return ACC->CCmd.size();
85}
86
87CXCompileCommand
88clang_CompileCommands_getCommand(CXCompileCommands Cmds, unsigned I)
89{
90  if (!Cmds)
91    return nullptr;
92
93  AllocatedCXCompileCommands *ACC =
94    static_cast<AllocatedCXCompileCommands *>(Cmds);
95
96  if (I >= ACC->CCmd.size())
97    return nullptr;
98
99  return &ACC->CCmd[I];
100}
101
102CXString
103clang_CompileCommand_getDirectory(CXCompileCommand CCmd)
104{
105  if (!CCmd)
106    return cxstring::createNull();
107
108  CompileCommand *cmd = static_cast<CompileCommand *>(CCmd);
109  return cxstring::createRef(cmd->Directory.c_str());
110}
111
112CXString
113clang_CompileCommand_getFilename(CXCompileCommand CCmd)
114{
115  if (!CCmd)
116    return cxstring::createNull();
117
118  CompileCommand *cmd = static_cast<CompileCommand *>(CCmd);
119  return cxstring::createRef(cmd->Filename.c_str());
120}
121
122unsigned
123clang_CompileCommand_getNumArgs(CXCompileCommand CCmd)
124{
125  if (!CCmd)
126    return 0;
127
128  return static_cast<CompileCommand *>(CCmd)->CommandLine.size();
129}
130
131CXString
132clang_CompileCommand_getArg(CXCompileCommand CCmd, unsigned Arg)
133{
134  if (!CCmd)
135    return cxstring::createNull();
136
137  CompileCommand *Cmd = static_cast<CompileCommand *>(CCmd);
138
139  if (Arg >= Cmd->CommandLine.size())
140    return cxstring::createNull();
141
142  return cxstring::createRef(Cmd->CommandLine[Arg].c_str());
143}
144
145unsigned
146clang_CompileCommand_getNumMappedSources(CXCompileCommand CCmd)
147{
148  // Left here for backward compatibility. No mapped sources exists in the C++
149  // backend anymore.
150  return 0;
151}
152
153CXString
154clang_CompileCommand_getMappedSourcePath(CXCompileCommand CCmd, unsigned I)
155{
156  // Left here for backward compatibility. No mapped sources exists in the C++
157  // backend anymore.
158  return cxstring::createNull();
159}
160
161CXString
162clang_CompileCommand_getMappedSourceContent(CXCompileCommand CCmd, unsigned I)
163{
164  // Left here for backward compatibility. No mapped sources exists in the C++
165  // backend anymore.
166  return cxstring::createNull();
167}
168