Introduce CompilationDatabase::getAllCompileCommands() that returns all
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Tue, 4 Dec 2012 07:26:44 +0000 (07:26 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Tue, 4 Dec 2012 07:26:44 +0000 (07:26 +0000)
compile commands of the database and expose it via the libclang API.

llvm-svn: 169226

clang/include/clang-c/CXCompilationDatabase.h
clang/include/clang-c/Index.h
clang/include/clang/Tooling/CompilationDatabase.h
clang/include/clang/Tooling/JSONCompilationDatabase.h
clang/lib/Tooling/CompilationDatabase.cpp
clang/lib/Tooling/JSONCompilationDatabase.cpp
clang/tools/libclang/CXCompilationDatabase.cpp
clang/tools/libclang/libclang.exports
clang/unittests/Tooling/CompilationDatabaseTest.cpp

index d11133c..ff1ec63 100644 (file)
@@ -95,6 +95,12 @@ 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
  */
 CINDEX_LINKAGE void clang_CompileCommands_dispose(CXCompileCommands);
index aa3403c..24c754d 100644 (file)
@@ -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)                       \
index a40bffe..d75cc5f 100644 (file)
@@ -106,6 +106,10 @@ public:
 
   /// \brief Returns the list of all files available in the compilation database.
   virtual std::vector<std::string> getAllFiles() const = 0;
+
+  /// \brief Returns all compile commands for all the files in the compilation
+  /// database.
+  virtual std::vector<CompileCommand> 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<std::string> 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<CompileCommand> getAllCompileCommands() const;
+
 private:
   /// This is built up to contain a single entry vector to be returned from
   /// getCompileCommands after adding the positional argument.
index d62ab5c..0424d94 100644 (file)
@@ -75,6 +75,10 @@ public:
   /// These are the 'file' entries of the JSON objects.
   virtual std::vector<std::string> getAllFiles() const;
 
+  /// \brief Returns all compile commands for all the files in the compilation
+  /// database.
+  virtual std::vector<CompileCommand> 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<llvm::yaml::ScalarNode*,
                     llvm::yaml::ScalarNode*> CompileCommandRef;
 
+  /// \brief Converts the given array of CompileCommandRefs to CompileCommands.
+  void getCommands(ArrayRef<CompileCommandRef> CommandsRef,
+                   std::vector<CompileCommand> &Commands) const;
+
   // Maps file paths to the compile command lines for that file.
   llvm::StringMap< std::vector<CompileCommandRef> > IndexByFile;
 
index 4149cda..ebdb965 100644 (file)
@@ -132,6 +132,11 @@ FixedCompilationDatabase::getAllFiles() const {
   return std::vector<std::string>();
 }
 
+std::vector<CompileCommand>
+FixedCompilationDatabase::getAllCompileCommands() const {
+  return std::vector<CompileCommand>();
+}
+
 // This anchor is used to force the linker to link in the generated object file
 // and thus register the JSONCompilationDatabasePlugin.
 extern volatile int JSONAnchorSource;
index cf35a25..d54e1d8 100644 (file)
@@ -178,16 +178,8 @@ JSONCompilationDatabase::getCompileCommands(StringRef FilePath) const {
     CommandsRefI = IndexByFile.find(Match);
   if (CommandsRefI == IndexByFile.end())
     return std::vector<CompileCommand>();
-  const std::vector<CompileCommandRef> &CommandsRef = CommandsRefI->getValue();
   std::vector<CompileCommand> 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<CompileCommand>
+JSONCompilationDatabase::getAllCompileCommands() const {
+  std::vector<CompileCommand> Commands;
+  for (llvm::StringMap< std::vector<CompileCommandRef> >::const_iterator
+        CommandsRefI = IndexByFile.begin(), CommandsRefEnd = IndexByFile.end();
+      CommandsRefI != CommandsRefEnd; ++CommandsRefI) {
+    getCommands(CommandsRefI->getValue(), Commands);
+  }
+  return Commands;
+}
+
+void JSONCompilationDatabase::getCommands(
+                                  ArrayRef<CompileCommandRef> CommandsRef,
+                                  std::vector<CompileCommand> &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()) {
index 7bd319a..8567d31 100644 (file)
@@ -59,6 +59,17 @@ clang_CompilationDatabase_getCompileCommands(CXCompilationDatabase CDb,
   return 0;
 }
 
+CXCompileCommands
+clang_CompilationDatabase_getAllCompileCommands(CXCompilationDatabase CDb) {
+  if (CompilationDatabase *db = static_cast<CompilationDatabase *>(CDb)) {
+    const std::vector<CompileCommand> CCmd(db->getAllCompileCommands());
+    if (!CCmd.empty())
+      return new AllocatedCXCompileCommands( CCmd );
+  }
+
+  return 0;
+}
+
 void
 clang_CompileCommands_dispose(CXCompileCommands Cmds)
 {
index 4495b66..ee34edc 100644 (file)
@@ -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
index 5ed4240..3abb818 100644 (file)
@@ -51,6 +51,17 @@ static std::vector<std::string> getAllFiles(StringRef JSONDatabase,
   return Database->getAllFiles();
 }
 
+static std::vector<CompileCommand> getAllCompileCommands(StringRef JSONDatabase,
+                                                    std::string &ErrorMessage) {
+  llvm::OwningPtr<CompilationDatabase> Database(
+      JSONCompilationDatabase::loadFromBuffer(JSONDatabase, ErrorMessage));
+  if (!Database) {
+    ADD_FAILURE() << ErrorMessage;
+    return std::vector<CompileCommand>();
+  }
+  return Database->getAllCompileCommands();
+}
+
 TEST(JSONCompilationDatabase, GetAllFiles) {
   std::string ErrorMessage;
   EXPECT_EQ(std::vector<std::string>(),
@@ -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<CompileCommand> 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<std::string> 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<FixedCompilationDatabase> Database(