From: David Blaikie Date: Fri, 8 Aug 2014 16:06:15 +0000 (+0000) Subject: CompilationDatabase: Sure-up ownership of compilation databases using std::unique_ptr X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1ad06b0994238227b9b38a4563ec2bedf02fbdba;p=clang CompilationDatabase: Sure-up ownership of compilation databases using std::unique_ptr 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 --- diff --git a/include/clang/Tooling/CompilationDatabase.h b/include/clang/Tooling/CompilationDatabase.h index d1e729a88b..7b0cbb07fb 100644 --- a/include/clang/Tooling/CompilationDatabase.h +++ b/include/clang/Tooling/CompilationDatabase.h @@ -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 + 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 + 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 + 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 + loadFromDirectory(StringRef Directory, std::string &ErrorMessage) = 0; }; /// \brief A compilation database that returns a single compile command line. diff --git a/include/clang/Tooling/JSONCompilationDatabase.h b/include/clang/Tooling/JSONCompilationDatabase.h index 1b33359685..5945156323 100644 --- a/include/clang/Tooling/JSONCompilationDatabase.h +++ b/include/clang/Tooling/JSONCompilationDatabase.h @@ -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 + 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 + loadFromBuffer(StringRef DatabaseString, std::string &ErrorMessage); /// \brief Returns all compile comamnds in which the specified file was /// compiled. diff --git a/lib/Tooling/CommonOptionsParser.cpp b/lib/Tooling/CommonOptionsParser.cpp index e0b844c067..c15f40d7f7 100644 --- a/lib/Tooling/CommonOptionsParser.cpp +++ b/lib/Tooling/CommonOptionsParser.cpp @@ -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); diff --git a/lib/Tooling/CompilationDatabase.cpp b/lib/Tooling/CompilationDatabase.cpp index 4b776bf3c7..02bcf02860 100644 --- a/lib/Tooling/CompilationDatabase.cpp +++ b/lib/Tooling/CompilationDatabase.cpp @@ -35,7 +35,7 @@ namespace tooling { CompilationDatabase::~CompilationDatabase() {} -CompilationDatabase * +std::unique_ptr 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 Plugin(It->instantiate()); - if (CompilationDatabase *DB = - Plugin->loadFromDirectory(BuildDirectory, DatabaseErrorMessage)) + if (std::unique_ptr 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 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 DB = + CompilationDatabase::loadFromDirectory(Directory, LoadErrorMessage)) return DB; if (!HasErrorMessage) { @@ -79,14 +78,14 @@ findCompilationDatabaseFromDirectory(StringRef Directory, return nullptr; } -CompilationDatabase * +std::unique_ptr 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 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::autoDetectFromDirectory(StringRef SourceDir, std::string &ErrorMessage) { SmallString<1024> AbsolutePath(getAbsolutePath(SourceDir)); - CompilationDatabase *DB = findCompilationDatabaseFromDirectory(AbsolutePath, - ErrorMessage); + std::unique_ptr DB = + findCompilationDatabaseFromDirectory(AbsolutePath, ErrorMessage); if (!DB) ErrorMessage = ("Could not auto-detect compilation database from directory \"" + diff --git a/lib/Tooling/JSONCompilationDatabase.cpp b/lib/Tooling/JSONCompilationDatabase.cpp index 8b8bd29385..088b42a0e4 100644 --- a/lib/Tooling/JSONCompilationDatabase.cpp +++ b/lib/Tooling/JSONCompilationDatabase.cpp @@ -118,15 +118,15 @@ std::vector unescapeCommandLine( } class JSONCompilationDatabasePlugin : public CompilationDatabasePlugin { - CompilationDatabase *loadFromDirectory(StringRef Directory, - std::string &ErrorMessage) override { + std::unique_ptr + loadFromDirectory(StringRef Directory, std::string &ErrorMessage) override { SmallString<1024> JSONDatabasePath(Directory); llvm::sys::path::append(JSONDatabasePath, "compile_commands.json"); std::unique_ptr 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::loadFromFile(StringRef FilePath, std::string &ErrorMessage) { llvm::ErrorOr> 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::loadFromBuffer(StringRef DatabaseString, std::string &ErrorMessage) { std::unique_ptr 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 diff --git a/tools/libclang/CXCompilationDatabase.cpp b/tools/libclang/CXCompilationDatabase.cpp index 51677e7210..1e4a2cd44a 100644 --- a/tools/libclang/CXCompilationDatabase.cpp +++ b/tools/libclang/CXCompilationDatabase.cpp @@ -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 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