From: Argyrios Kyrtzidis Date: Tue, 4 Dec 2012 07:26:44 +0000 (+0000) Subject: Introduce CompilationDatabase::getAllCompileCommands() that returns all X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7e96bfb4d507700a122f270a11ce3fc0e8e36c85;p=clang Introduce CompilationDatabase::getAllCompileCommands() that returns all compile commands of the database and expose it via the libclang API. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@169226 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang-c/CXCompilationDatabase.h b/include/clang-c/CXCompilationDatabase.h index d11133cf93..ff1ec63db0 100644 --- a/include/clang-c/CXCompilationDatabase.h +++ b/include/clang-c/CXCompilationDatabase.h @@ -94,6 +94,12 @@ CINDEX_LINKAGE CXCompileCommands clang_CompilationDatabase_getCompileCommands(CXCompilationDatabase, const char *CompleteFileName); +/** + * \brief Get all the compile commands in the given compilation database. + */ +CINDEX_LINKAGE CXCompileCommands +clang_CompilationDatabase_getAllCompileCommands(CXCompilationDatabase); + /** * \brief Free the given CompileCommands */ diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h index aa3403cc80..24c754d995 100644 --- a/include/clang-c/Index.h +++ b/include/clang-c/Index.h @@ -32,7 +32,7 @@ * compatible, thus CINDEX_VERSION_MAJOR is expected to remain stable. */ #define CINDEX_VERSION_MAJOR 0 -#define CINDEX_VERSION_MINOR 6 +#define CINDEX_VERSION_MINOR 7 #define CINDEX_VERSION_ENCODE(major, minor) ( \ ((major) * 10000) \ diff --git a/include/clang/Tooling/CompilationDatabase.h b/include/clang/Tooling/CompilationDatabase.h index a40bffec78..d75cc5fc34 100644 --- a/include/clang/Tooling/CompilationDatabase.h +++ b/include/clang/Tooling/CompilationDatabase.h @@ -106,6 +106,10 @@ public: /// \brief Returns the list of all files available in the compilation database. virtual std::vector getAllFiles() const = 0; + + /// \brief Returns all compile commands for all the files in the compilation + /// database. + virtual std::vector getAllCompileCommands() const = 0; }; /// \brief Interface for compilation database plugins. @@ -181,6 +185,12 @@ public: /// Note: This is always an empty list for the fixed compilation database. virtual std::vector getAllFiles() const; + /// \brief Returns all compile commands for all the files in the compilation + /// database. + /// + /// Note: This is always an empty list for the fixed compilation database. + virtual std::vector getAllCompileCommands() const; + private: /// This is built up to contain a single entry vector to be returned from /// getCompileCommands after adding the positional argument. diff --git a/include/clang/Tooling/JSONCompilationDatabase.h b/include/clang/Tooling/JSONCompilationDatabase.h index d62ab5c503..0424d94629 100644 --- a/include/clang/Tooling/JSONCompilationDatabase.h +++ b/include/clang/Tooling/JSONCompilationDatabase.h @@ -75,6 +75,10 @@ public: /// These are the 'file' entries of the JSON objects. virtual std::vector getAllFiles() const; + /// \brief Returns all compile commands for all the files in the compilation + /// database. + virtual std::vector getAllCompileCommands() const; + private: /// \brief Constructs a JSON compilation database on a memory buffer. JSONCompilationDatabase(llvm::MemoryBuffer *Database) @@ -91,6 +95,10 @@ private: typedef std::pair CompileCommandRef; + /// \brief Converts the given array of CompileCommandRefs to CompileCommands. + void getCommands(ArrayRef CommandsRef, + std::vector &Commands) const; + // Maps file paths to the compile command lines for that file. llvm::StringMap< std::vector > IndexByFile; diff --git a/lib/Tooling/CompilationDatabase.cpp b/lib/Tooling/CompilationDatabase.cpp index 4149cda378..ebdb96519c 100644 --- a/lib/Tooling/CompilationDatabase.cpp +++ b/lib/Tooling/CompilationDatabase.cpp @@ -132,6 +132,11 @@ FixedCompilationDatabase::getAllFiles() const { return std::vector(); } +std::vector +FixedCompilationDatabase::getAllCompileCommands() const { + return std::vector(); +} + // This anchor is used to force the linker to link in the generated object file // and thus register the JSONCompilationDatabasePlugin. extern volatile int JSONAnchorSource; diff --git a/lib/Tooling/JSONCompilationDatabase.cpp b/lib/Tooling/JSONCompilationDatabase.cpp index cf35a25666..d54e1d86a0 100644 --- a/lib/Tooling/JSONCompilationDatabase.cpp +++ b/lib/Tooling/JSONCompilationDatabase.cpp @@ -178,16 +178,8 @@ JSONCompilationDatabase::getCompileCommands(StringRef FilePath) const { CommandsRefI = IndexByFile.find(Match); if (CommandsRefI == IndexByFile.end()) return std::vector(); - const std::vector &CommandsRef = CommandsRefI->getValue(); std::vector Commands; - for (int I = 0, E = CommandsRef.size(); I != E; ++I) { - llvm::SmallString<8> DirectoryStorage; - llvm::SmallString<1024> CommandStorage; - Commands.push_back(CompileCommand( - // FIXME: Escape correctly: - CommandsRef[I].first->getValue(DirectoryStorage), - unescapeCommandLine(CommandsRef[I].second->getValue(CommandStorage)))); - } + getCommands(CommandsRefI->getValue(), Commands); return Commands; } @@ -206,6 +198,30 @@ JSONCompilationDatabase::getAllFiles() const { return Result; } +std::vector +JSONCompilationDatabase::getAllCompileCommands() const { + std::vector Commands; + for (llvm::StringMap< std::vector >::const_iterator + CommandsRefI = IndexByFile.begin(), CommandsRefEnd = IndexByFile.end(); + CommandsRefI != CommandsRefEnd; ++CommandsRefI) { + getCommands(CommandsRefI->getValue(), Commands); + } + return Commands; +} + +void JSONCompilationDatabase::getCommands( + ArrayRef CommandsRef, + std::vector &Commands) const { + for (int I = 0, E = CommandsRef.size(); I != E; ++I) { + llvm::SmallString<8> DirectoryStorage; + llvm::SmallString<1024> CommandStorage; + Commands.push_back(CompileCommand( + // FIXME: Escape correctly: + CommandsRef[I].first->getValue(DirectoryStorage), + unescapeCommandLine(CommandsRef[I].second->getValue(CommandStorage)))); + } +} + bool JSONCompilationDatabase::parse(std::string &ErrorMessage) { llvm::yaml::document_iterator I = YAMLStream.begin(); if (I == YAMLStream.end()) { diff --git a/tools/libclang/CXCompilationDatabase.cpp b/tools/libclang/CXCompilationDatabase.cpp index 7bd319ac29..8567d318a2 100644 --- a/tools/libclang/CXCompilationDatabase.cpp +++ b/tools/libclang/CXCompilationDatabase.cpp @@ -59,6 +59,17 @@ clang_CompilationDatabase_getCompileCommands(CXCompilationDatabase CDb, return 0; } +CXCompileCommands +clang_CompilationDatabase_getAllCompileCommands(CXCompilationDatabase CDb) { + if (CompilationDatabase *db = static_cast(CDb)) { + const std::vector CCmd(db->getAllCompileCommands()); + if (!CCmd.empty()) + return new AllocatedCXCompileCommands( CCmd ); + } + + return 0; +} + void clang_CompileCommands_dispose(CXCompileCommands Cmds) { diff --git a/tools/libclang/libclang.exports b/tools/libclang/libclang.exports index 4495b66bdc..ee34edcbb2 100644 --- a/tools/libclang/libclang.exports +++ b/tools/libclang/libclang.exports @@ -250,6 +250,7 @@ clang_tokenize clang_CompilationDatabase_fromDirectory clang_CompilationDatabase_dispose clang_CompilationDatabase_getCompileCommands +clang_CompilationDatabase_getAllCompileCommands clang_CompileCommands_dispose clang_CompileCommands_getSize clang_CompileCommands_getCommand diff --git a/unittests/Tooling/CompilationDatabaseTest.cpp b/unittests/Tooling/CompilationDatabaseTest.cpp index 5ed4240c1e..3abb818ff2 100644 --- a/unittests/Tooling/CompilationDatabaseTest.cpp +++ b/unittests/Tooling/CompilationDatabaseTest.cpp @@ -51,6 +51,17 @@ static std::vector getAllFiles(StringRef JSONDatabase, return Database->getAllFiles(); } +static std::vector getAllCompileCommands(StringRef JSONDatabase, + std::string &ErrorMessage) { + llvm::OwningPtr Database( + JSONCompilationDatabase::loadFromBuffer(JSONDatabase, ErrorMessage)); + if (!Database) { + ADD_FAILURE() << ErrorMessage; + return std::vector(); + } + return Database->getAllCompileCommands(); +} + TEST(JSONCompilationDatabase, GetAllFiles) { std::string ErrorMessage; EXPECT_EQ(std::vector(), @@ -72,6 +83,35 @@ TEST(JSONCompilationDatabase, GetAllFiles) { ErrorMessage)) << ErrorMessage; } +TEST(JSONCompilationDatabase, GetAllCompileCommands) { + std::string ErrorMessage; + EXPECT_EQ(0u, + getAllCompileCommands("[]", ErrorMessage).size()) << ErrorMessage; + + StringRef Directory1("//net/dir1"); + StringRef FileName1("file1"); + StringRef Command1("command1"); + StringRef Directory2("//net/dir2"); + StringRef FileName2("file1"); + StringRef Command2("command1"); + + std::vector Commands = getAllCompileCommands( + ("[{\"directory\":\"" + Directory1 + "\"," + + "\"command\":\"" + Command1 + "\"," + "\"file\":\"" + FileName1 + "\"}," + " {\"directory\":\"" + Directory2 + "\"," + + "\"command\":\"" + Command2 + "\"," + "\"file\":\"" + FileName2 + "\"}]").str(), + ErrorMessage); + EXPECT_EQ(2U, Commands.size()) << ErrorMessage; + EXPECT_EQ(Directory1, Commands[0].Directory) << ErrorMessage; + ASSERT_EQ(1u, Commands[0].CommandLine.size()); + EXPECT_EQ(Command1, Commands[0].CommandLine[0]) << ErrorMessage; + EXPECT_EQ(Directory2, Commands[1].Directory) << ErrorMessage; + ASSERT_EQ(1u, Commands[1].CommandLine.size()); + EXPECT_EQ(Command2, Commands[1].CommandLine[0]) << ErrorMessage; +} + static CompileCommand findCompileArgsInJsonDatabase(StringRef FileName, StringRef JSONDatabase, std::string &ErrorMessage) { @@ -376,6 +416,15 @@ TEST(FixedCompilationDatabase, GetAllFiles) { EXPECT_EQ(0ul, Database.getAllFiles().size()); } +TEST(FixedCompilationDatabase, GetAllCompileCommands) { + std::vector CommandLine; + CommandLine.push_back("one"); + CommandLine.push_back("two"); + FixedCompilationDatabase Database(".", CommandLine); + + EXPECT_EQ(0ul, Database.getAllCompileCommands().size()); +} + TEST(ParseFixedCompilationDatabase, ReturnsNullOnEmptyArgumentList) { int Argc = 0; llvm::OwningPtr Database(