From 4187df5f7bdda66d2fbe64a3f2660ee3977f0d12 Mon Sep 17 00:00:00 2001 From: "Arnaud A. de Grandmaison" Date: Tue, 10 Jul 2012 16:56:35 +0000 Subject: [PATCH] Adds support for auto-detection of compilation databases, looking in a directory and all its parents. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@159998 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Tooling/CompilationDatabase.h | 11 +++++- lib/Tooling/CompilationDatabase.cpp | 42 ++++++++++++++++----- test/Tooling/clang-check-autodetect-dir.cpp | 11 ++++++ tools/clang-check/ClangCheck.cpp | 5 ++- 4 files changed, 56 insertions(+), 13 deletions(-) create mode 100644 test/Tooling/clang-check-autodetect-dir.cpp diff --git a/include/clang/Tooling/CompilationDatabase.h b/include/clang/Tooling/CompilationDatabase.h index 0dec6f8f87..143c65e313 100644 --- a/include/clang/Tooling/CompilationDatabase.h +++ b/include/clang/Tooling/CompilationDatabase.h @@ -83,11 +83,18 @@ public: /// \brief Tries to detect a compilation database location and load it. /// - /// Looks for a compilation database in all parent paths by calling - /// loadFromDirectory. + /// Looks for a compilation database in all parent paths of file 'SourceFile' + /// by calling loadFromDirectory. static 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); + /// \brief Returns all compile commands in which the specified file was /// compiled. /// diff --git a/lib/Tooling/CompilationDatabase.cpp b/lib/Tooling/CompilationDatabase.cpp index 8e911123bc..a06343ddab 100644 --- a/lib/Tooling/CompilationDatabase.cpp +++ b/lib/Tooling/CompilationDatabase.cpp @@ -122,23 +122,47 @@ CompilationDatabase::loadFromDirectory(StringRef BuildDirectory, return Database.take(); } -CompilationDatabase * -CompilationDatabase::autoDetectFromSource(StringRef SourceFile, - std::string &ErrorMessage) { - llvm::SmallString<1024> AbsolutePath(getAbsolutePath(SourceFile)); - StringRef Directory = llvm::sys::path::parent_path(AbsolutePath); +static CompilationDatabase * +findCompilationDatabaseFromDirectory(StringRef Directory) { while (!Directory.empty()) { std::string LoadErrorMessage; - if (CompilationDatabase *DB = loadFromDirectory(Directory, - LoadErrorMessage)) + + if (CompilationDatabase *DB = + CompilationDatabase::loadFromDirectory(Directory, LoadErrorMessage)) return DB; + Directory = llvm::sys::path::parent_path(Directory); } - ErrorMessage = ("Could not auto-detect compilation database for file \"" + - SourceFile + "\"").str(); return NULL; } +CompilationDatabase * +CompilationDatabase::autoDetectFromSource(StringRef SourceFile, + std::string &ErrorMessage) { + llvm::SmallString<1024> AbsolutePath(getAbsolutePath(SourceFile)); + StringRef Directory = llvm::sys::path::parent_path(AbsolutePath); + + CompilationDatabase *DB = findCompilationDatabaseFromDirectory(Directory); + + if (!DB) + ErrorMessage = ("Could not auto-detect compilation database for file \"" + + SourceFile + "\"").str(); + return DB; +} + +CompilationDatabase * +CompilationDatabase::autoDetectFromDirectory(StringRef SourceDir, + std::string &ErrorMessage) { + llvm::SmallString<1024> AbsolutePath(getAbsolutePath(SourceDir)); + + CompilationDatabase *DB = findCompilationDatabaseFromDirectory(AbsolutePath); + + if (!DB) + ErrorMessage = ("Could not auto-detect compilation database from directory \"" + + SourceDir + "\"").str(); + return DB; +} + FixedCompilationDatabase * FixedCompilationDatabase::loadFromCommandLine(int &Argc, const char **Argv, diff --git a/test/Tooling/clang-check-autodetect-dir.cpp b/test/Tooling/clang-check-autodetect-dir.cpp new file mode 100644 index 0000000000..2c395043bf --- /dev/null +++ b/test/Tooling/clang-check-autodetect-dir.cpp @@ -0,0 +1,11 @@ +// RUN: rm -rf %t +// RUN: mkdir -p %t/abc/def +// RUN: echo "[{\"directory\":\".\",\"command\":\"clang++ -c %t/test.cpp\",\"file\":\"%t/test.cpp\"}]" | sed -e 's/\\/\\\\/g' > %t/compile_commands.json +// RUN: cp "%s" "%t/test.cpp" +// RUN: clang-check -p "%t/abc/def" "%t/test.cpp" 2>&1|FileCheck %s +// FIXME: Make the above easier. + +// CHECK: C++ requires +invalid; + +// REQUIRES: shell diff --git a/tools/clang-check/ClangCheck.cpp b/tools/clang-check/ClangCheck.cpp index ef4a3ace0c..d51d90e906 100644 --- a/tools/clang-check/ClangCheck.cpp +++ b/tools/clang-check/ClangCheck.cpp @@ -58,8 +58,9 @@ int main(int argc, const char **argv) { if (!Compilations) { std::string ErrorMessage; if (!BuildPath.empty()) { - Compilations.reset(CompilationDatabase::loadFromDirectory(BuildPath, - ErrorMessage)); + Compilations.reset( + CompilationDatabase::autoDetectFromDirectory(BuildPath, ErrorMessage)); + } else { Compilations.reset(CompilationDatabase::autoDetectFromSource( SourcePaths[0], ErrorMessage)); -- 2.50.1