12b3c8603SArnaud A. de Grandmaison #include "clang-c/CXCompilationDatabase.h"
22b3c8603SArnaud A. de Grandmaison #include "CXString.h"
3cc0694c8SChandler Carruth #include "clang/Tooling/CompilationDatabase.h"
4ab458a13SDmitri Gribenko #include <cstdio>
52b3c8603SArnaud A. de Grandmaison 
62b3c8603SArnaud A. de Grandmaison using namespace clang;
72b3c8603SArnaud A. de Grandmaison using namespace clang::tooling;
82b3c8603SArnaud A. de Grandmaison 
92b3c8603SArnaud A. de Grandmaison extern "C" {
102b3c8603SArnaud A. de Grandmaison 
11f6a24ce4SAlp Toker // FIXME: do something more useful with the error message
122b3c8603SArnaud A. de Grandmaison CXCompilationDatabase
13fa6d73ccSArnaud A. de Grandmaison clang_CompilationDatabase_fromDirectory(const char *BuildDir,
142b3c8603SArnaud A. de Grandmaison                                         CXCompilationDatabase_Error *ErrorCode)
152b3c8603SArnaud A. de Grandmaison {
162b3c8603SArnaud A. de Grandmaison   std::string ErrorMsg;
172b3c8603SArnaud A. de Grandmaison   CXCompilationDatabase_Error Err = CXCompilationDatabase_NoError;
182b3c8603SArnaud A. de Grandmaison 
19*cdba84c0SDavid Blaikie   std::unique_ptr<CompilationDatabase> db =
20*cdba84c0SDavid Blaikie       CompilationDatabase::loadFromDirectory(BuildDir, ErrorMsg);
212b3c8603SArnaud A. de Grandmaison 
222b3c8603SArnaud A. de Grandmaison   if (!db) {
232b3c8603SArnaud A. de Grandmaison     fprintf(stderr, "LIBCLANG TOOLING ERROR: %s\n", ErrorMsg.c_str());
242b3c8603SArnaud A. de Grandmaison     Err = CXCompilationDatabase_CanNotLoadDatabase;
252b3c8603SArnaud A. de Grandmaison   }
262b3c8603SArnaud A. de Grandmaison 
272b3c8603SArnaud A. de Grandmaison   if (ErrorCode)
282b3c8603SArnaud A. de Grandmaison     *ErrorCode = Err;
292b3c8603SArnaud A. de Grandmaison 
30*cdba84c0SDavid Blaikie   return db.release();
312b3c8603SArnaud A. de Grandmaison }
322b3c8603SArnaud A. de Grandmaison 
332b3c8603SArnaud A. de Grandmaison void
34fa6d73ccSArnaud A. de Grandmaison clang_CompilationDatabase_dispose(CXCompilationDatabase CDb)
352b3c8603SArnaud A. de Grandmaison {
362b3c8603SArnaud A. de Grandmaison   delete static_cast<CompilationDatabase *>(CDb);
372b3c8603SArnaud A. de Grandmaison }
382b3c8603SArnaud A. de Grandmaison 
392b3c8603SArnaud A. de Grandmaison struct AllocatedCXCompileCommands
402b3c8603SArnaud A. de Grandmaison {
412b3c8603SArnaud A. de Grandmaison   std::vector<CompileCommand> CCmd;
422b3c8603SArnaud A. de Grandmaison 
43efb1eb98SBenjamin Kramer   AllocatedCXCompileCommands(std::vector<CompileCommand> Cmd)
44efb1eb98SBenjamin Kramer       : CCmd(std::move(Cmd)) {}
452b3c8603SArnaud A. de Grandmaison };
462b3c8603SArnaud A. de Grandmaison 
472b3c8603SArnaud A. de Grandmaison CXCompileCommands
48fa6d73ccSArnaud A. de Grandmaison clang_CompilationDatabase_getCompileCommands(CXCompilationDatabase CDb,
492b3c8603SArnaud A. de Grandmaison                                              const char *CompleteFileName)
502b3c8603SArnaud A. de Grandmaison {
512b3c8603SArnaud A. de Grandmaison   if (CompilationDatabase *db = static_cast<CompilationDatabase *>(CDb)) {
52efb1eb98SBenjamin Kramer     std::vector<CompileCommand> CCmd(db->getCompileCommands(CompleteFileName));
532b3c8603SArnaud A. de Grandmaison     if (!CCmd.empty())
54efb1eb98SBenjamin Kramer       return new AllocatedCXCompileCommands(std::move(CCmd));
552b3c8603SArnaud A. de Grandmaison   }
562b3c8603SArnaud A. de Grandmaison 
5769186e73SCraig Topper   return nullptr;
582b3c8603SArnaud A. de Grandmaison }
592b3c8603SArnaud A. de Grandmaison 
60251ad5e0SArgyrios Kyrtzidis CXCompileCommands
61251ad5e0SArgyrios Kyrtzidis clang_CompilationDatabase_getAllCompileCommands(CXCompilationDatabase CDb) {
62251ad5e0SArgyrios Kyrtzidis   if (CompilationDatabase *db = static_cast<CompilationDatabase *>(CDb)) {
63efb1eb98SBenjamin Kramer     std::vector<CompileCommand> CCmd(db->getAllCompileCommands());
64251ad5e0SArgyrios Kyrtzidis     if (!CCmd.empty())
65efb1eb98SBenjamin Kramer       return new AllocatedCXCompileCommands(std::move(CCmd));
66251ad5e0SArgyrios Kyrtzidis   }
67251ad5e0SArgyrios Kyrtzidis 
6869186e73SCraig Topper   return nullptr;
69251ad5e0SArgyrios Kyrtzidis }
70251ad5e0SArgyrios Kyrtzidis 
712b3c8603SArnaud A. de Grandmaison void
72fa6d73ccSArnaud A. de Grandmaison clang_CompileCommands_dispose(CXCompileCommands Cmds)
732b3c8603SArnaud A. de Grandmaison {
742b3c8603SArnaud A. de Grandmaison   delete static_cast<AllocatedCXCompileCommands *>(Cmds);
752b3c8603SArnaud A. de Grandmaison }
762b3c8603SArnaud A. de Grandmaison 
772b3c8603SArnaud A. de Grandmaison unsigned
78fa6d73ccSArnaud A. de Grandmaison clang_CompileCommands_getSize(CXCompileCommands Cmds)
792b3c8603SArnaud A. de Grandmaison {
802b3c8603SArnaud A. de Grandmaison   if (!Cmds)
812b3c8603SArnaud A. de Grandmaison     return 0;
822b3c8603SArnaud A. de Grandmaison 
832b3c8603SArnaud A. de Grandmaison   AllocatedCXCompileCommands *ACC =
842b3c8603SArnaud A. de Grandmaison     static_cast<AllocatedCXCompileCommands *>(Cmds);
852b3c8603SArnaud A. de Grandmaison 
862b3c8603SArnaud A. de Grandmaison   return ACC->CCmd.size();
872b3c8603SArnaud A. de Grandmaison }
882b3c8603SArnaud A. de Grandmaison 
892b3c8603SArnaud A. de Grandmaison CXCompileCommand
90fa6d73ccSArnaud A. de Grandmaison clang_CompileCommands_getCommand(CXCompileCommands Cmds, unsigned I)
912b3c8603SArnaud A. de Grandmaison {
922b3c8603SArnaud A. de Grandmaison   if (!Cmds)
9369186e73SCraig Topper     return nullptr;
942b3c8603SArnaud A. de Grandmaison 
952b3c8603SArnaud A. de Grandmaison   AllocatedCXCompileCommands *ACC =
962b3c8603SArnaud A. de Grandmaison     static_cast<AllocatedCXCompileCommands *>(Cmds);
972b3c8603SArnaud A. de Grandmaison 
982b3c8603SArnaud A. de Grandmaison   if (I >= ACC->CCmd.size())
9969186e73SCraig Topper     return nullptr;
1002b3c8603SArnaud A. de Grandmaison 
1012b3c8603SArnaud A. de Grandmaison   return &ACC->CCmd[I];
1022b3c8603SArnaud A. de Grandmaison }
1032b3c8603SArnaud A. de Grandmaison 
1042b3c8603SArnaud A. de Grandmaison CXString
105fa6d73ccSArnaud A. de Grandmaison clang_CompileCommand_getDirectory(CXCompileCommand CCmd)
1062b3c8603SArnaud A. de Grandmaison {
1072b3c8603SArnaud A. de Grandmaison   if (!CCmd)
108f98dfbaeSDmitri Gribenko     return cxstring::createNull();
1092b3c8603SArnaud A. de Grandmaison 
1102b3c8603SArnaud A. de Grandmaison   CompileCommand *cmd = static_cast<CompileCommand *>(CCmd);
1113c66b0beSDmitri Gribenko   return cxstring::createRef(cmd->Directory.c_str());
1122b3c8603SArnaud A. de Grandmaison }
1132b3c8603SArnaud A. de Grandmaison 
1142b3c8603SArnaud A. de Grandmaison unsigned
115fa6d73ccSArnaud A. de Grandmaison clang_CompileCommand_getNumArgs(CXCompileCommand CCmd)
1162b3c8603SArnaud A. de Grandmaison {
1172b3c8603SArnaud A. de Grandmaison   if (!CCmd)
1182b3c8603SArnaud A. de Grandmaison     return 0;
1192b3c8603SArnaud A. de Grandmaison 
1202b3c8603SArnaud A. de Grandmaison   return static_cast<CompileCommand *>(CCmd)->CommandLine.size();
1212b3c8603SArnaud A. de Grandmaison }
1222b3c8603SArnaud A. de Grandmaison 
1232b3c8603SArnaud A. de Grandmaison CXString
124fa6d73ccSArnaud A. de Grandmaison clang_CompileCommand_getArg(CXCompileCommand CCmd, unsigned Arg)
1252b3c8603SArnaud A. de Grandmaison {
1262b3c8603SArnaud A. de Grandmaison   if (!CCmd)
127f98dfbaeSDmitri Gribenko     return cxstring::createNull();
1282b3c8603SArnaud A. de Grandmaison 
1292b3c8603SArnaud A. de Grandmaison   CompileCommand *Cmd = static_cast<CompileCommand *>(CCmd);
1302b3c8603SArnaud A. de Grandmaison 
1312b3c8603SArnaud A. de Grandmaison   if (Arg >= Cmd->CommandLine.size())
132f98dfbaeSDmitri Gribenko     return cxstring::createNull();
1332b3c8603SArnaud A. de Grandmaison 
1343c66b0beSDmitri Gribenko   return cxstring::createRef(Cmd->CommandLine[Arg].c_str());
1352b3c8603SArnaud A. de Grandmaison }
1362b3c8603SArnaud A. de Grandmaison 
1376192c93aSManuel Klimek unsigned
1386192c93aSManuel Klimek clang_CompileCommand_getNumMappedSources(CXCompileCommand CCmd)
1396192c93aSManuel Klimek {
1406192c93aSManuel Klimek   if (!CCmd)
1416192c93aSManuel Klimek     return 0;
1426192c93aSManuel Klimek 
1436192c93aSManuel Klimek   return static_cast<CompileCommand *>(CCmd)->MappedSources.size();
1446192c93aSManuel Klimek }
1456192c93aSManuel Klimek 
1466192c93aSManuel Klimek CXString
1476192c93aSManuel Klimek clang_CompileCommand_getMappedSourcePath(CXCompileCommand CCmd, unsigned I)
1486192c93aSManuel Klimek {
1496192c93aSManuel Klimek   if (!CCmd)
1506192c93aSManuel Klimek     return cxstring::createNull();
1516192c93aSManuel Klimek 
1526192c93aSManuel Klimek   CompileCommand *Cmd = static_cast<CompileCommand *>(CCmd);
1536192c93aSManuel Klimek 
1546192c93aSManuel Klimek   if (I >= Cmd->MappedSources.size())
1556192c93aSManuel Klimek     return cxstring::createNull();
1566192c93aSManuel Klimek 
1576192c93aSManuel Klimek   return cxstring::createRef(Cmd->MappedSources[I].first.c_str());
1586192c93aSManuel Klimek }
1596192c93aSManuel Klimek 
1606192c93aSManuel Klimek CXString
1616192c93aSManuel Klimek clang_CompileCommand_getMappedSourceContent(CXCompileCommand CCmd, unsigned I)
1626192c93aSManuel Klimek {
1636192c93aSManuel Klimek   if (!CCmd)
1646192c93aSManuel Klimek     return cxstring::createNull();
1656192c93aSManuel Klimek 
1666192c93aSManuel Klimek   CompileCommand *Cmd = static_cast<CompileCommand *>(CCmd);
1676192c93aSManuel Klimek 
1686192c93aSManuel Klimek   if (I >= Cmd->MappedSources.size())
1696192c93aSManuel Klimek     return cxstring::createNull();
1706192c93aSManuel Klimek 
1716192c93aSManuel Klimek   return cxstring::createRef(Cmd->MappedSources[I].second.c_str());
1726192c93aSManuel Klimek }
1732b3c8603SArnaud A. de Grandmaison 
1742b3c8603SArnaud A. de Grandmaison } // end: extern "C"
175