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