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