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 unsigned
clang_CompileCommand_getNumArgs(CXCompileCommand CCmd)115 clang_CompileCommand_getNumArgs(CXCompileCommand CCmd)
116 {
117   if (!CCmd)
118     return 0;
119 
120   return static_cast<CompileCommand *>(CCmd)->CommandLine.size();
121 }
122 
123 CXString
clang_CompileCommand_getArg(CXCompileCommand CCmd,unsigned Arg)124 clang_CompileCommand_getArg(CXCompileCommand CCmd, unsigned Arg)
125 {
126   if (!CCmd)
127     return cxstring::createNull();
128 
129   CompileCommand *Cmd = static_cast<CompileCommand *>(CCmd);
130 
131   if (Arg >= Cmd->CommandLine.size())
132     return cxstring::createNull();
133 
134   return cxstring::createRef(Cmd->CommandLine[Arg].c_str());
135 }
136 
137 unsigned
clang_CompileCommand_getNumMappedSources(CXCompileCommand CCmd)138 clang_CompileCommand_getNumMappedSources(CXCompileCommand CCmd)
139 {
140   if (!CCmd)
141     return 0;
142 
143   return static_cast<CompileCommand *>(CCmd)->MappedSources.size();
144 }
145 
146 CXString
clang_CompileCommand_getMappedSourcePath(CXCompileCommand CCmd,unsigned I)147 clang_CompileCommand_getMappedSourcePath(CXCompileCommand CCmd, unsigned I)
148 {
149   if (!CCmd)
150     return cxstring::createNull();
151 
152   CompileCommand *Cmd = static_cast<CompileCommand *>(CCmd);
153 
154   if (I >= Cmd->MappedSources.size())
155     return cxstring::createNull();
156 
157   return cxstring::createRef(Cmd->MappedSources[I].first.c_str());
158 }
159 
160 CXString
clang_CompileCommand_getMappedSourceContent(CXCompileCommand CCmd,unsigned I)161 clang_CompileCommand_getMappedSourceContent(CXCompileCommand CCmd, unsigned I)
162 {
163   if (!CCmd)
164     return cxstring::createNull();
165 
166   CompileCommand *Cmd = static_cast<CompileCommand *>(CCmd);
167 
168   if (I >= Cmd->MappedSources.size())
169     return cxstring::createNull();
170 
171   return cxstring::createRef(Cmd->MappedSources[I].second.c_str());
172 }
173 
174 } // end: extern "C"
175