CompilationDatabase: Sure-up ownership of compilation databases using std::unique_ptr
authorDavid Blaikie <dblaikie@gmail.com>
Fri, 8 Aug 2014 16:06:15 +0000 (16:06 +0000)
committerDavid Blaikie <dblaikie@gmail.com>
Fri, 8 Aug 2014 16:06:15 +0000 (16:06 +0000)
Diving into the memory leaks fixed by r213851 there was one case of a
memory leak of a CompilationDatabase due to not properly taking
ownership of the result of "CompilationDatabase::autoDetectFromSource".
Given that both implementations and callers have been using unique_ptr
to own CompilationDatabase objects - make this explicit in the API to
reduce the risk of further leaks.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@215215 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Tooling/CompilationDatabase.h
include/clang/Tooling/JSONCompilationDatabase.h
lib/Tooling/CommonOptionsParser.cpp
lib/Tooling/CompilationDatabase.cpp
lib/Tooling/JSONCompilationDatabase.cpp
tools/libclang/CXCompilationDatabase.cpp

index d1e729a88b27ba86a2c7276d1ae8849987c906a9..7b0cbb07fb5679b525f470c670856790835d3251 100644 (file)
@@ -84,22 +84,22 @@ public:
   /// FIXME: Currently only supports JSON compilation databases, which
   /// are named 'compile_commands.json' in the given directory. Extend this
   /// for other build types (like ninja build files).
-  static CompilationDatabase *loadFromDirectory(StringRef BuildDirectory,
-                                                std::string &ErrorMessage);
+  static std::unique_ptr<CompilationDatabase>
+  loadFromDirectory(StringRef BuildDirectory, std::string &ErrorMessage);
 
   /// \brief Tries to detect a compilation database location and load it.
   ///
   /// Looks for a compilation database in all parent paths of file 'SourceFile'
   /// by calling loadFromDirectory.
-  static CompilationDatabase *autoDetectFromSource(StringRef SourceFile,
-                                                   std::string &ErrorMessage);
+  static std::unique_ptr<CompilationDatabase>
+  autoDetectFromSource(StringRef SourceFile, std::string &ErrorMessage);
 
   /// \brief Tries to detect a compilation database location and load it.
   ///
   /// Looks for a compilation database in directory 'SourceDir' and all
   /// its parent paths by calling loadFromDirectory.
-  static CompilationDatabase *autoDetectFromDirectory(StringRef SourceDir,
-                                                      std::string &ErrorMessage);
+  static std::unique_ptr<CompilationDatabase>
+  autoDetectFromDirectory(StringRef SourceDir, std::string &ErrorMessage);
 
   /// \brief Returns all compile commands in which the specified file was
   /// compiled.
@@ -142,8 +142,8 @@ public:
   /// \brief Loads a compilation database from a build directory.
   ///
   /// \see CompilationDatabase::loadFromDirectory().
-  virtual CompilationDatabase *loadFromDirectory(StringRef Directory,
-                                                 std::string &ErrorMessage) = 0;
+  virtual std::unique_ptr<CompilationDatabase>
+  loadFromDirectory(StringRef Directory, std::string &ErrorMessage) = 0;
 };
 
 /// \brief A compilation database that returns a single compile command line.
index 1b3335968594e29b47f9bc3d2787bd12ebeb10cc..59451563236bfac5dfadd919c2fd01d84589b6fd 100644 (file)
@@ -53,14 +53,14 @@ public:
   ///
   /// Returns NULL and sets ErrorMessage if the database could not be
   /// loaded from the given file.
-  static JSONCompilationDatabase *loadFromFile(StringRef FilePath,
-                                               std::string &ErrorMessage);
+  static std::unique_ptr<JSONCompilationDatabase>
+  loadFromFile(StringRef FilePath, std::string &ErrorMessage);
 
   /// \brief Loads a JSON compilation database from a data buffer.
   ///
   /// Returns NULL and sets ErrorMessage if the database could not be loaded.
-  static JSONCompilationDatabase *loadFromBuffer(StringRef DatabaseString,
-                                                 std::string &ErrorMessage);
+  static std::unique_ptr<JSONCompilationDatabase>
+  loadFromBuffer(StringRef DatabaseString, std::string &ErrorMessage);
 
   /// \brief Returns all compile comamnds in which the specified file was
   /// compiled.
index e0b844c067d4fead9c677472339969feecfa11f3..c15f40d7f793050d54b5e6cfed4dbafaeade5b35 100644 (file)
@@ -82,11 +82,11 @@ CommonOptionsParser::CommonOptionsParser(int &argc, const char **argv,
   if (!Compilations) {
     std::string ErrorMessage;
     if (!BuildPath.empty()) {
-      Compilations.reset(CompilationDatabase::autoDetectFromDirectory(
-                              BuildPath, ErrorMessage));
+      Compilations =
+          CompilationDatabase::autoDetectFromDirectory(BuildPath, ErrorMessage);
     } else {
-      Compilations.reset(CompilationDatabase::autoDetectFromSource(
-                              SourcePaths[0], ErrorMessage));
+      Compilations = CompilationDatabase::autoDetectFromSource(SourcePaths[0],
+                                                               ErrorMessage);
     }
     if (!Compilations)
       llvm::report_fatal_error(ErrorMessage);
index 4b776bf3c73dd4842925e9cd0b7975f897b4582b..02bcf02860cb8ee6866cc2fa248f8c85e1862b80 100644 (file)
@@ -35,7 +35,7 @@ namespace tooling {
 
 CompilationDatabase::~CompilationDatabase() {}
 
-CompilationDatabase *
+std::unique_ptr<CompilationDatabase>
 CompilationDatabase::loadFromDirectory(StringRef BuildDirectory,
                                        std::string &ErrorMessage) {
   std::stringstream ErrorStream;
@@ -45,17 +45,16 @@ CompilationDatabase::loadFromDirectory(StringRef BuildDirectory,
        It != Ie; ++It) {
     std::string DatabaseErrorMessage;
     std::unique_ptr<CompilationDatabasePlugin> Plugin(It->instantiate());
-    if (CompilationDatabase *DB =
-        Plugin->loadFromDirectory(BuildDirectory, DatabaseErrorMessage))
+    if (std::unique_ptr<CompilationDatabase> DB =
+            Plugin->loadFromDirectory(BuildDirectory, DatabaseErrorMessage))
       return DB;
-    else
-      ErrorStream << It->getName() << ": " << DatabaseErrorMessage << "\n";
+    ErrorStream << It->getName() << ": " << DatabaseErrorMessage << "\n";
   }
   ErrorMessage = ErrorStream.str();
   return nullptr;
 }
 
-static CompilationDatabase *
+static std::unique_ptr<CompilationDatabase>
 findCompilationDatabaseFromDirectory(StringRef Directory,
                                      std::string &ErrorMessage) {
   std::stringstream ErrorStream;
@@ -63,8 +62,8 @@ findCompilationDatabaseFromDirectory(StringRef Directory,
   while (!Directory.empty()) {
     std::string LoadErrorMessage;
 
-    if (CompilationDatabase *DB =
-           CompilationDatabase::loadFromDirectory(Directory, LoadErrorMessage))
+    if (std::unique_ptr<CompilationDatabase> DB =
+            CompilationDatabase::loadFromDirectory(Directory, LoadErrorMessage))
       return DB;
 
     if (!HasErrorMessage) {
@@ -79,14 +78,14 @@ findCompilationDatabaseFromDirectory(StringRef Directory,
   return nullptr;
 }
 
-CompilationDatabase *
+std::unique_ptr<CompilationDatabase>
 CompilationDatabase::autoDetectFromSource(StringRef SourceFile,
                                           std::string &ErrorMessage) {
   SmallString<1024> AbsolutePath(getAbsolutePath(SourceFile));
   StringRef Directory = llvm::sys::path::parent_path(AbsolutePath);
 
-  CompilationDatabase *DB = findCompilationDatabaseFromDirectory(Directory,
-                                                                 ErrorMessage);
+  std::unique_ptr<CompilationDatabase> DB =
+      findCompilationDatabaseFromDirectory(Directory, ErrorMessage);
 
   if (!DB)
     ErrorMessage = ("Could not auto-detect compilation database for file \"" +
@@ -94,13 +93,13 @@ CompilationDatabase::autoDetectFromSource(StringRef SourceFile,
   return DB;
 }
 
-CompilationDatabase *
+std::unique_ptr<CompilationDatabase>
 CompilationDatabase::autoDetectFromDirectory(StringRef SourceDir,
                                              std::string &ErrorMessage) {
   SmallString<1024> AbsolutePath(getAbsolutePath(SourceDir));
 
-  CompilationDatabase *DB = findCompilationDatabaseFromDirectory(AbsolutePath,
-                                                                 ErrorMessage);
+  std::unique_ptr<CompilationDatabase> DB =
+      findCompilationDatabaseFromDirectory(AbsolutePath, ErrorMessage);
 
   if (!DB)
     ErrorMessage = ("Could not auto-detect compilation database from directory \"" +
index 8b8bd293851f3713ed9f2d4e6c2f9223e81744d2..088b42a0e4b230b333e2390f606ac331ad4eff63 100644 (file)
@@ -118,15 +118,15 @@ std::vector<std::string> unescapeCommandLine(
 }
 
 class JSONCompilationDatabasePlugin : public CompilationDatabasePlugin {
-  CompilationDatabase *loadFromDirectory(StringRef Directory,
-                                         std::string &ErrorMessage) override {
+  std::unique_ptr<CompilationDatabase>
+  loadFromDirectory(StringRef Directory, std::string &ErrorMessage) override {
     SmallString<1024> JSONDatabasePath(Directory);
     llvm::sys::path::append(JSONDatabasePath, "compile_commands.json");
     std::unique_ptr<CompilationDatabase> Database(
         JSONCompilationDatabase::loadFromFile(JSONDatabasePath, ErrorMessage));
     if (!Database)
       return nullptr;
-    return Database.release();
+    return Database;
   }
 };
 
@@ -141,7 +141,7 @@ X("json-compilation-database", "Reads JSON formatted compilation databases");
 // and thus register the JSONCompilationDatabasePlugin.
 volatile int JSONAnchorSource = 0;
 
-JSONCompilationDatabase *
+std::unique_ptr<JSONCompilationDatabase>
 JSONCompilationDatabase::loadFromFile(StringRef FilePath,
                                       std::string &ErrorMessage) {
   llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> DatabaseBuffer =
@@ -154,10 +154,10 @@ JSONCompilationDatabase::loadFromFile(StringRef FilePath,
       new JSONCompilationDatabase(DatabaseBuffer->release()));
   if (!Database->parse(ErrorMessage))
     return nullptr;
-  return Database.release();
+  return Database;
 }
 
-JSONCompilationDatabase *
+std::unique_ptr<JSONCompilationDatabase>
 JSONCompilationDatabase::loadFromBuffer(StringRef DatabaseString,
                                         std::string &ErrorMessage) {
   std::unique_ptr<llvm::MemoryBuffer> DatabaseBuffer(
@@ -166,7 +166,7 @@ JSONCompilationDatabase::loadFromBuffer(StringRef DatabaseString,
       new JSONCompilationDatabase(DatabaseBuffer.release()));
   if (!Database->parse(ErrorMessage))
     return nullptr;
-  return Database.release();
+  return Database;
 }
 
 std::vector<CompileCommand>
index 51677e7210350b8195e1c0753c14194523aaaeee..1e4a2cd44aabbb29a3fa3664957ae316ce229b8c 100644 (file)
@@ -16,8 +16,8 @@ clang_CompilationDatabase_fromDirectory(const char *BuildDir,
   std::string ErrorMsg;
   CXCompilationDatabase_Error Err = CXCompilationDatabase_NoError;
 
-  CompilationDatabase *db = CompilationDatabase::loadFromDirectory(BuildDir,
-                                                                   ErrorMsg);
+  std::unique_ptr<CompilationDatabase> db =
+      CompilationDatabase::loadFromDirectory(BuildDir, ErrorMsg);
 
   if (!db) {
     fprintf(stderr, "LIBCLANG TOOLING ERROR: %s\n", ErrorMsg.c_str());
@@ -27,7 +27,7 @@ clang_CompilationDatabase_fromDirectory(const char *BuildDir,
   if (ErrorCode)
     *ErrorCode = Err;
 
-  return db;
+  return db.release();
 }
 
 void