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 usefull with the error message
12 CXCompilationDatabase
13 clang_CompilationDatabase_fromDirectory(const char *BuildDir,
14                                         CXCompilationDatabase_Error *ErrorCode)
15 {
16   std::string ErrorMsg;
17   CXCompilationDatabase_Error Err = CXCompilationDatabase_NoError;
18 
19   CompilationDatabase *db = CompilationDatabase::loadFromDirectory(BuildDir,
20                                                                    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;
31 }
32 
33 void
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 
43   AllocatedCXCompileCommands(const std::vector<CompileCommand>& Cmd)
44     : CCmd(Cmd)
45   { }
46 };
47 
48 CXCompileCommands
49 clang_CompilationDatabase_getCompileCommands(CXCompilationDatabase CDb,
50                                              const char *CompleteFileName)
51 {
52   if (CompilationDatabase *db = static_cast<CompilationDatabase *>(CDb)) {
53     const std::vector<CompileCommand>
54       CCmd(db->getCompileCommands(CompleteFileName));
55     if (!CCmd.empty())
56       return new AllocatedCXCompileCommands( CCmd );
57   }
58 
59   return 0;
60 }
61 
62 CXCompileCommands
63 clang_CompilationDatabase_getAllCompileCommands(CXCompilationDatabase CDb) {
64   if (CompilationDatabase *db = static_cast<CompilationDatabase *>(CDb)) {
65     const std::vector<CompileCommand> CCmd(db->getAllCompileCommands());
66     if (!CCmd.empty())
67       return new AllocatedCXCompileCommands( CCmd );
68   }
69 
70   return 0;
71 }
72 
73 void
74 clang_CompileCommands_dispose(CXCompileCommands Cmds)
75 {
76   delete static_cast<AllocatedCXCompileCommands *>(Cmds);
77 }
78 
79 unsigned
80 clang_CompileCommands_getSize(CXCompileCommands Cmds)
81 {
82   if (!Cmds)
83     return 0;
84 
85   AllocatedCXCompileCommands *ACC =
86     static_cast<AllocatedCXCompileCommands *>(Cmds);
87 
88   return ACC->CCmd.size();
89 }
90 
91 CXCompileCommand
92 clang_CompileCommands_getCommand(CXCompileCommands Cmds, unsigned I)
93 {
94   if (!Cmds)
95     return 0;
96 
97   AllocatedCXCompileCommands *ACC =
98     static_cast<AllocatedCXCompileCommands *>(Cmds);
99 
100   if (I >= ACC->CCmd.size())
101     return 0;
102 
103   return &ACC->CCmd[I];
104 }
105 
106 CXString
107 clang_CompileCommand_getDirectory(CXCompileCommand CCmd)
108 {
109   if (!CCmd)
110     return cxstring::createNull();
111 
112   CompileCommand *cmd = static_cast<CompileCommand *>(CCmd);
113   return cxstring::createRef(cmd->Directory.c_str());
114 }
115 
116 unsigned
117 clang_CompileCommand_getNumArgs(CXCompileCommand CCmd)
118 {
119   if (!CCmd)
120     return 0;
121 
122   return static_cast<CompileCommand *>(CCmd)->CommandLine.size();
123 }
124 
125 CXString
126 clang_CompileCommand_getArg(CXCompileCommand CCmd, unsigned Arg)
127 {
128   if (!CCmd)
129     return cxstring::createNull();
130 
131   CompileCommand *Cmd = static_cast<CompileCommand *>(CCmd);
132 
133   if (Arg >= Cmd->CommandLine.size())
134     return cxstring::createNull();
135 
136   return cxstring::createRef(Cmd->CommandLine[Arg].c_str());
137 }
138 
139 unsigned
140 clang_CompileCommand_getNumMappedSources(CXCompileCommand CCmd)
141 {
142   if (!CCmd)
143     return 0;
144 
145   return static_cast<CompileCommand *>(CCmd)->MappedSources.size();
146 }
147 
148 CXString
149 clang_CompileCommand_getMappedSourcePath(CXCompileCommand CCmd, unsigned I)
150 {
151   if (!CCmd)
152     return cxstring::createNull();
153 
154   CompileCommand *Cmd = static_cast<CompileCommand *>(CCmd);
155 
156   if (I >= Cmd->MappedSources.size())
157     return cxstring::createNull();
158 
159   return cxstring::createRef(Cmd->MappedSources[I].first.c_str());
160 }
161 
162 CXString
163 clang_CompileCommand_getMappedSourceContent(CXCompileCommand CCmd, unsigned I)
164 {
165   if (!CCmd)
166     return cxstring::createNull();
167 
168   CompileCommand *Cmd = static_cast<CompileCommand *>(CCmd);
169 
170   if (I >= Cmd->MappedSources.size())
171     return cxstring::createNull();
172 
173   return cxstring::createRef(Cmd->MappedSources[I].second.c_str());
174 }
175 
176 } // end: extern "C"
177