hokein updated this revision to Diff 72963.
hokein added a comment.

Correct the implementation of FixedCompilationDatabase::getCommonRoot.


https://reviews.llvm.org/D25027

Files:
  include/clang/Tooling/CompilationDatabase.h
  include/clang/Tooling/JSONCompilationDatabase.h
  lib/Tooling/CommonOptionsParser.cpp
  lib/Tooling/CompilationDatabase.cpp
  lib/Tooling/JSONCompilationDatabase.cpp
  unittests/Tooling/CompilationDatabaseTest.cpp

Index: unittests/Tooling/CompilationDatabaseTest.cpp
===================================================================
--- unittests/Tooling/CompilationDatabaseTest.cpp
+++ unittests/Tooling/CompilationDatabaseTest.cpp
@@ -95,6 +95,34 @@
       << ErrorMessage;
 }
 
+TEST(JSONCompilationDatabase, GetCommonRoot) {
+  std::string ErrorMessage;
+  std::string JSONDatabase = "[{\"directory\":\"//dir/build/\","
+                             "\"command\":\"command\","
+                             "\"file\":\"file1\"},"
+                             " {\"directory\":\"//dir/build/\","
+                             "\"command\":\"command\","
+                             "\"file\":\"file2\"}]";
+
+  std::unique_ptr<CompilationDatabase> Database(
+      JSONCompilationDatabase::loadFromBuffer(JSONDatabase, ErrorMessage,
+                                              JSONCommandLineSyntax::Gnu));
+  auto CommonRoot = Database->getCommonRoot();
+  ASSERT_TRUE(CommonRoot.hasValue());
+  EXPECT_EQ("//dir/build/", *CommonRoot);
+
+  JSONDatabase = "[{\"directory\":\"//dir/build/\","
+                 "\"command\":\"command\","
+                 "\"file\":\"file1\"},"
+                 " {\"directory\":\"//dir/build2/\","
+                 "\"command\":\"command\","
+                 "\"file\":\"file2\"}]";
+  Database = JSONCompilationDatabase::loadFromBuffer(
+      JSONDatabase, ErrorMessage, JSONCommandLineSyntax::Gnu);
+  CommonRoot = Database->getCommonRoot();
+  EXPECT_FALSE(CommonRoot.hasValue());
+}
+
 TEST(JSONCompilationDatabase, GetAllCompileCommands) {
   std::string ErrorMessage;
   EXPECT_EQ(
Index: lib/Tooling/JSONCompilationDatabase.cpp
===================================================================
--- lib/Tooling/JSONCompilationDatabase.cpp
+++ lib/Tooling/JSONCompilationDatabase.cpp
@@ -366,6 +366,20 @@
     AllCommands.push_back(Cmd);
     MatchTrie.insert(NativeFilePath);
   }
+  if (!AllCommands.empty()) {
+    SmallString<128> DirectoryStorage;
+    SmallString<128> NextDirectoryStorage;
+    llvm::StringRef Directory =
+        std::get<0>(AllCommands[0])->getValue(DirectoryStorage);
+    auto It = std::find_if(
+        AllCommands.begin() + 1, AllCommands.end(),
+        [&](JSONCompilationDatabase::CompileCommandRef &Command) {
+          return Directory !=
+                 std::get<0>(Command)->getValue(NextDirectoryStorage);
+        });
+    if (It == AllCommands.end())
+      CommonRoot = Directory.str();
+  }
   return true;
 }
 
Index: lib/Tooling/CompilationDatabase.cpp
===================================================================
--- lib/Tooling/CompilationDatabase.cpp
+++ lib/Tooling/CompilationDatabase.cpp
@@ -322,6 +322,17 @@
   return std::vector<CompileCommand>();
 }
 
+llvm::Optional<std::string> FixedCompilationDatabase::getCommonRoot() const {
+  auto It =
+      std::find_if(CompileCommands.begin(), CompileCommands.end(),
+                   [&](const clang::tooling::CompileCommand &Command) {
+                     return CompileCommands[0].Directory != Command.Directory;
+                   });
+  if (It == CompileCommands.end())
+    return CompileCommands[0].Directory;
+  return llvm::None;
+}
+
 namespace clang {
 namespace tooling {
 
Index: lib/Tooling/CommonOptionsParser.cpp
===================================================================
--- lib/Tooling/CommonOptionsParser.cpp
+++ lib/Tooling/CommonOptionsParser.cpp
@@ -78,6 +78,10 @@
     return adjustCommands(Compilations->getAllCompileCommands());
   }
 
+  llvm::Optional<std::string> getCommonRoot() const override {
+    return Compilations->getCommonRoot();
+  }
+
 private:
   std::unique_ptr<CompilationDatabase> Compilations;
   std::vector<ArgumentsAdjuster> Adjusters;
Index: include/clang/Tooling/JSONCompilationDatabase.h
===================================================================
--- include/clang/Tooling/JSONCompilationDatabase.h
+++ include/clang/Tooling/JSONCompilationDatabase.h
@@ -90,12 +90,18 @@
   /// database.
   std::vector<CompileCommand> getAllCompileCommands() const override;
 
+  /// \brief Returns the common build directory for all translation units in the
+  /// JSON compilation database.
+  llvm::Optional<std::string> getCommonRoot() const override {
+    return CommonRoot;
+  }
+
 private:
   /// \brief Constructs a JSON compilation database on a memory buffer.
   JSONCompilationDatabase(std::unique_ptr<llvm::MemoryBuffer> Database,
                           JSONCommandLineSyntax Syntax)
       : Database(std::move(Database)), Syntax(Syntax),
-        YAMLStream(this->Database->getBuffer(), SM) {}
+        YAMLStream(this->Database->getBuffer(), SM), CommonRoot(llvm::None) {}
 
   /// \brief Parses the database file and creates the index.
   ///
@@ -130,6 +136,8 @@
   JSONCommandLineSyntax Syntax;
   llvm::SourceMgr SM;
   llvm::yaml::Stream YAMLStream;
+
+  llvm::Optional<std::string> CommonRoot;
 };
 
 } // end namespace tooling
Index: include/clang/Tooling/CompilationDatabase.h
===================================================================
--- include/clang/Tooling/CompilationDatabase.h
+++ include/clang/Tooling/CompilationDatabase.h
@@ -122,6 +122,11 @@
   /// \brief Returns the list of all files available in the compilation database.
   virtual std::vector<std::string> getAllFiles() const = 0;
 
+  /// \brief Returns the common build directory for all translation units in the
+  /// compilation database. Return None if there are different build
+  /// directories.
+  virtual llvm::Optional<std::string> getCommonRoot() const = 0;
+
   /// \brief Returns all compile commands for all the files in the compilation
   /// database.
   ///
@@ -210,6 +215,10 @@
   /// Note: This is always an empty list for the fixed compilation database.
   std::vector<CompileCommand> getAllCompileCommands() const override;
 
+  /// \brief Returns the common build directory for all translation units in the
+  /// compilation database.
+  llvm::Optional<std::string> getCommonRoot() const override;
+
 private:
   /// This is built up to contain a single entry vector to be returned from
   /// getCompileCommands after adding the positional argument.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to