[cfe-commits] r156299 - in /cfe/trunk: include/clang/Tooling/Tooling.h lib/Tooling/Tooling.cpp test/Tooling/clang-check-chdir.cpp

Manuel Klimek klimek at google.com
Mon May 7 02:17:48 PDT 2012


Author: klimek
Date: Mon May  7 04:17:48 2012
New Revision: 156299

URL: http://llvm.org/viewvc/llvm-project?rev=156299&view=rev
Log:
Fixes resolution of relative paths when running clang tools.

The chdir is not the perfect fix, as it is thread hostile. The
real fix will be to make -working-dir work correctly, which will
take time to implement. Before that, the tooling library cannot
be used concurrently.


Added:
    cfe/trunk/test/Tooling/clang-check-chdir.cpp   (with props)
Modified:
    cfe/trunk/include/clang/Tooling/Tooling.h
    cfe/trunk/lib/Tooling/Tooling.cpp

Modified: cfe/trunk/include/clang/Tooling/Tooling.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Tooling.h?rev=156299&r1=156298&r2=156299&view=diff
==============================================================================
--- cfe/trunk/include/clang/Tooling/Tooling.h (original)
+++ cfe/trunk/include/clang/Tooling/Tooling.h Mon May  7 04:17:48 2012
@@ -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 @@
 
 namespace tooling {
 
-class CompilationDatabase;
-
 /// \brief Interface to generate clang::FrontendActions.
 class FrontendActionFactory {
 public:
@@ -169,9 +168,8 @@
   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>).

Modified: cfe/trunk/lib/Tooling/Tooling.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/Tooling.cpp?rev=156299&r1=156298&r2=156299&view=diff
==============================================================================
--- cfe/trunk/lib/Tooling/Tooling.cpp (original)
+++ cfe/trunk/lib/Tooling/Tooling.cpp Mon May  7 04:17:48 2012
@@ -256,18 +256,12 @@
     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 @@
 
 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) {

Added: cfe/trunk/test/Tooling/clang-check-chdir.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Tooling/clang-check-chdir.cpp?rev=156299&view=auto
==============================================================================
--- cfe/trunk/test/Tooling/clang-check-chdir.cpp (added)
+++ cfe/trunk/test/Tooling/clang-check-chdir.cpp Mon May  7 04:17:48 2012
@@ -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

Propchange: cfe/trunk/test/Tooling/clang-check-chdir.cpp
------------------------------------------------------------------------------
    svn:eol-style = LF





More information about the cfe-commits mailing list