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 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 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(std::vector<CompileCommand> Cmd) 44 : CCmd(std::move(Cmd)) {} 45 }; 46 47 CXCompileCommands 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 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 72 clang_CompileCommands_dispose(CXCompileCommands Cmds) 73 { 74 delete static_cast<AllocatedCXCompileCommands *>(Cmds); 75 } 76 77 unsigned 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 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 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 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 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 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 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 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 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