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.

llvm-svn: 156299
diff --git a/clang/lib/Tooling/Tooling.cpp b/clang/lib/Tooling/Tooling.cpp
index 646a22a..6ab71e2 100644
--- a/clang/lib/Tooling/Tooling.cpp
+++ b/clang/lib/Tooling/Tooling.cpp
@@ -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) {