From: Alexander Kornienko Date: Mon, 10 Nov 2014 15:42:31 +0000 (+0000) Subject: [Tooling] Restore current directory after processing each file. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ffbc78615ca28683a980a3fc5ca41c3466fb3b67;p=clang [Tooling] Restore current directory after processing each file. Summary: If we actually change directory before processing a file, we need to restore it afterwards. This was broken in r216620. Added a comment for the changes in r216620. Reviewers: klimek Reviewed By: klimek Subscribers: klimek, cfe-commits Differential Revision: http://reviews.llvm.org/D6162 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@221600 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Tooling/Tooling.cpp b/lib/Tooling/Tooling.cpp index 7109584f53..64613ded3e 100644 --- a/lib/Tooling/Tooling.cpp +++ b/lib/Tooling/Tooling.cpp @@ -301,10 +301,21 @@ int ClangTool::run(ToolAction *Action) { std::string MainExecutable = llvm::sys::fs::getMainExecutable("clang_tool", &StaticSymbol); + llvm::SmallString<128> InitialDirectory; + if (std::error_code EC = llvm::sys::fs::current_path(InitialDirectory)) + llvm::report_fatal_error("Cannot detect current path: " + + Twine(EC.message())); bool ProcessingFailed = false; for (const auto &SourcePath : SourcePaths) { std::string File(getAbsolutePath(SourcePath)); + // Currently implementations of CompilationDatabase::getCompileCommands can + // change the state of the file system (e.g. prepare generated headers), so + // this method needs to run right before we invoke the tool, as the next + // file may require a different (incompatible) state of the file system. + // + // FIXME: Make the compilation database interface more explicit about the + // requirements to the order of invocation of its members. std::vector CompileCommandsForFile = Compilations.getCompileCommands(File); if (CompileCommandsForFile.empty()) { @@ -337,14 +348,18 @@ int ClangTool::run(ToolAction *Action) { DEBUG({ llvm::dbgs() << "Processing: " << File << ".\n"; }); ToolInvocation Invocation(std::move(CommandLine), Action, Files.get()); Invocation.setDiagnosticConsumer(DiagConsumer); - for (const auto &MappedFile : MappedFileContents) { + for (const auto &MappedFile : MappedFileContents) Invocation.mapVirtualFile(MappedFile.first, MappedFile.second); - } if (!Invocation.run()) { // FIXME: Diagnostics should be used instead. llvm::errs() << "Error while processing " << File << ".\n"; ProcessingFailed = true; } + // Return to the initial directory to correctly resolve next file by + // relative path. + if (chdir(InitialDirectory.c_str())) + llvm::report_fatal_error("Cannot chdir into \"" + + Twine(InitialDirectory) + "\n!"); } } return ProcessingFailed ? 1 : 0;