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 // FIXME: do something more useful with the error message
10 CXCompilationDatabase
clang_CompilationDatabase_fromDirectory(const char * BuildDir,CXCompilationDatabase_Error * ErrorCode)11 clang_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 
31 void
clang_CompilationDatabase_dispose(CXCompilationDatabase CDb)32 clang_CompilationDatabase_dispose(CXCompilationDatabase CDb)
33 {
34   delete static_cast<CompilationDatabase *>(CDb);
35 }
36 
37 struct AllocatedCXCompileCommands
38 {
39   std::vector<CompileCommand> CCmd;
40 
AllocatedCXCompileCommandsAllocatedCXCompileCommands41   AllocatedCXCompileCommands(std::vector<CompileCommand> Cmd)
42       : CCmd(std::move(Cmd)) {}
43 };
44 
45 CXCompileCommands
clang_CompilationDatabase_getCompileCommands(CXCompilationDatabase CDb,const char * CompleteFileName)46 clang_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 
58 CXCompileCommands
clang_CompilationDatabase_getAllCompileCommands(CXCompilationDatabase CDb)59 clang_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 
69 void
clang_CompileCommands_dispose(CXCompileCommands Cmds)70 clang_CompileCommands_dispose(CXCompileCommands Cmds)
71 {
72   delete static_cast<AllocatedCXCompileCommands *>(Cmds);
73 }
74 
75 unsigned
clang_CompileCommands_getSize(CXCompileCommands Cmds)76 clang_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 
87 CXCompileCommand
clang_CompileCommands_getCommand(CXCompileCommands Cmds,unsigned I)88 clang_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 
102 CXString
clang_CompileCommand_getDirectory(CXCompileCommand CCmd)103 clang_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 
112 CXString
clang_CompileCommand_getFilename(CXCompileCommand CCmd)113 clang_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 
122 unsigned
clang_CompileCommand_getNumArgs(CXCompileCommand CCmd)123 clang_CompileCommand_getNumArgs(CXCompileCommand CCmd)
124 {
125   if (!CCmd)
126     return 0;
127 
128   return static_cast<CompileCommand *>(CCmd)->CommandLine.size();
129 }
130 
131 CXString
clang_CompileCommand_getArg(CXCompileCommand CCmd,unsigned Arg)132 clang_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 
145 unsigned
clang_CompileCommand_getNumMappedSources(CXCompileCommand CCmd)146 clang_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 
153 CXString
clang_CompileCommand_getMappedSourcePath(CXCompileCommand CCmd,unsigned I)154 clang_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 
161 CXString
clang_CompileCommand_getMappedSourceContent(CXCompileCommand CCmd,unsigned I)162 clang_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