forked from OSchip/llvm-project
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. llvm-svn: 215215
This commit is contained in:
parent
590e5ff473
commit
cdba84c0d3
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 \"" +
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue