diff options
-rw-r--r-- | include/clang/Tooling/Tooling.h | 8 | ||||
-rw-r--r-- | lib/Tooling/Tooling.cpp | 33 | ||||
-rw-r--r-- | test/Tooling/clang-check-chdir.cpp | 18 |
3 files changed, 40 insertions, 19 deletions
diff --git a/include/clang/Tooling/Tooling.h b/include/clang/Tooling/Tooling.h index 25ed36b726..ff66616dfc 100644 --- a/include/clang/Tooling/Tooling.h +++ b/include/clang/Tooling/Tooling.h @@ -35,6 +35,7 @@ #include "clang/Basic/FileManager.h" #include "clang/Basic/LLVM.h" #include "clang/Driver/Util.h" +#include "clang/Tooling/CompilationDatabase.h" #include <string> #include <vector> @@ -50,8 +51,6 @@ class FrontendAction; namespace tooling { -class CompilationDatabase; - /// \brief Interface to generate clang::FrontendActions. class FrontendActionFactory { public: @@ -169,9 +168,8 @@ class ClangTool { FileManager &getFiles() { return Files; } private: - // We store command lines as pair (file name, command line). - typedef std::pair< std::string, std::vector<std::string> > CommandLine; - std::vector<CommandLine> CommandLines; + // We store compile commands as pair (file name, compile command). + std::vector< std::pair<std::string, CompileCommand> > CompileCommands; FileManager Files; // Contains a list of pairs (<file name>, <file content>). diff --git a/lib/Tooling/Tooling.cpp b/lib/Tooling/Tooling.cpp index 646a22af87..6ab71e2043 100644 --- a/lib/Tooling/Tooling.cpp +++ b/lib/Tooling/Tooling.cpp @@ -256,18 +256,12 @@ ClangTool::ClangTool(const CompilationDatabase &Compilations, llvm::SmallString<1024> File(getAbsolutePath( SourcePaths[I], BaseDirectory)); - std::vector<CompileCommand> CompileCommands = + std::vector<CompileCommand> CompileCommandsForFile = Compilations.getCompileCommands(File.str()); - if (!CompileCommands.empty()) { - for (int I = 0, E = CompileCommands.size(); I != E; ++I) { - CompileCommand &Command = CompileCommands[I]; - if (!Command.Directory.empty()) { - // FIXME: What should happen if CommandLine includes -working-directory - // as well? - Command.CommandLine.push_back( - "-working-directory=" + Command.Directory); - } - CommandLines.push_back(std::make_pair(File.str(), Command.CommandLine)); + if (!CompileCommandsForFile.empty()) { + for (int I = 0, E = CompileCommandsForFile.size(); I != E; ++I) { + CompileCommands.push_back(std::make_pair(File.str(), + CompileCommandsForFile[I])); } } else { // FIXME: There are two use cases here: doing a fuzzy @@ -286,9 +280,20 @@ void ClangTool::mapVirtualFile(StringRef FilePath, StringRef Content) { int ClangTool::run(FrontendActionFactory *ActionFactory) { bool ProcessingFailed = false; - for (unsigned I = 0; I < CommandLines.size(); ++I) { - std::string File = CommandLines[I].first; - std::vector<std::string> &CommandLine = CommandLines[I].second; + for (unsigned I = 0; I < CompileCommands.size(); ++I) { + std::string File = CompileCommands[I].first; + // FIXME: chdir is thread hostile; on the other hand, creating the same + // behavior as chdir is complex: chdir resolves the path once, thus + // guaranteeing that all subsequent relative path operations work + // on the same path the original chdir resulted in. This makes a difference + // for example on network filesystems, where symlinks might be switched + // during runtime of the tool. Fixing this depends on having a file system + // abstraction that allows openat() style interactions. + if (chdir(CompileCommands[I].second.Directory.c_str())) + llvm::report_fatal_error("Cannot chdir into \"" + + CompileCommands[I].second.Directory + "\n!"); + std::vector<std::string> &CommandLine = + CompileCommands[I].second.CommandLine; llvm::outs() << "Processing: " << File << ".\n"; ToolInvocation Invocation(CommandLine, ActionFactory->create(), &Files); for (int I = 0, E = MappedFileContents.size(); I != E; ++I) { diff --git a/test/Tooling/clang-check-chdir.cpp b/test/Tooling/clang-check-chdir.cpp new file mode 100644 index 0000000000..fbcd7ae3e8 --- /dev/null +++ b/test/Tooling/clang-check-chdir.cpp @@ -0,0 +1,18 @@ +// Verifies that paths are resolved relatively to the directory specified in the +// compilation database. +// RUN: rm -rf %t +// RUN: mkdir %t +// RUN: echo "[{\"directory\":\"%t\",\"command\":\"clang -c test.cpp -I.\",\"file\":\"%t/test.cpp\"}]" > %t/compile_commands.json +// RUN: cp "%s" "%t/test.cpp" +// RUN: touch "%t/clang-check-test.h" +// RUN: clang-check "%t" "%t/test.cpp" 2>&1|FileCheck %s +// FIXME: Make the above easier. + +#include "clang-check-test.h" + +// CHECK: C++ requires +invalid; + +// FIXME: JSON doesn't like path separator '\', on Win32 hosts. +// FIXME: clang-check doesn't like gcc driver on cygming. +// XFAIL: cygwin,mingw32,win32 |