summaryrefslogtreecommitdiffstats
path: root/clang/lib/Tooling/Tooling.cpp
diff options
context:
space:
mode:
authorIlya Biryukov <ibiryukov@google.com>2018-08-29 16:35:31 +0000
committerIlya Biryukov <ibiryukov@google.com>2018-08-29 16:35:31 +0000
commit2dbbd910dd2b1fde9e6960882c9f91c37351c81c (patch)
tree44a54a791f610ac9d07bd4d92e466658161ee882 /clang/lib/Tooling/Tooling.cpp
parent9250c92d0e28b0c475556a73c9fc43518891c659 (diff)
downloadbcm5719-llvm-2dbbd910dd2b1fde9e6960882c9f91c37351c81c.tar.gz
bcm5719-llvm-2dbbd910dd2b1fde9e6960882c9f91c37351c81c.zip
[Tooling] Do not restore working dir in ClangTool
Summary: Resolve all relative paths before running the tool instead. This fixes the usage of ClangTool in AllTUsExecutor. The executor will try running multiple ClangTool instances in parallel with compile commands that usually have the same working directory. Changing working directory is a global operation, so we end up changing working directory in the middle of running other actions, which leads to spurious compile errors. Reviewers: ioeric, sammccall Reviewed By: ioeric Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D51407 llvm-svn: 340937
Diffstat (limited to 'clang/lib/Tooling/Tooling.cpp')
-rw-r--r--clang/lib/Tooling/Tooling.cpp41
1 files changed, 22 insertions, 19 deletions
diff --git a/clang/lib/Tooling/Tooling.cpp b/clang/lib/Tooling/Tooling.cpp
index a106154f4b2..1ec285cc47e 100644
--- a/clang/lib/Tooling/Tooling.cpp
+++ b/clang/lib/Tooling/Tooling.cpp
@@ -199,7 +199,8 @@ bool runToolOnCodeWithArgs(
FileName, ToolName);
}
-std::string getAbsolutePath(StringRef File) {
+llvm::Expected<std::string> getAbsolutePath(vfs::FileSystem &FS,
+ StringRef File) {
StringRef RelativePath(File);
// FIXME: Should '.\\' be accepted on Win32?
if (RelativePath.startswith("./")) {
@@ -207,13 +208,16 @@ std::string getAbsolutePath(StringRef File) {
}
SmallString<1024> AbsolutePath = RelativePath;
- std::error_code EC = llvm::sys::fs::make_absolute(AbsolutePath);
- assert(!EC);
- (void)EC;
+ if (auto EC = FS.makeAbsolute(AbsolutePath))
+ return llvm::errorCodeToError(EC);
llvm::sys::path::native(AbsolutePath);
return AbsolutePath.str();
}
+std::string getAbsolutePath(StringRef File) {
+ return llvm::cantFail(getAbsolutePath(*vfs::getRealFileSystem(), File));
+}
+
void addTargetAndModeForProgramName(std::vector<std::string> &CommandLine,
StringRef InvokedAs) {
if (!CommandLine.empty() && !InvokedAs.empty()) {
@@ -411,15 +415,6 @@ int ClangTool::run(ToolAction *Action) {
// This just needs to be some symbol in the binary.
static int StaticSymbol;
- std::string InitialDirectory;
- if (llvm::ErrorOr<std::string> CWD =
- OverlayFileSystem->getCurrentWorkingDirectory()) {
- InitialDirectory = std::move(*CWD);
- } else {
- llvm::report_fatal_error("Cannot detect current path: " +
- Twine(CWD.getError().message()));
- }
-
// First insert all absolute paths into the in-memory VFS. These are global
// for all compile commands.
if (SeenWorkingDirectories.insert("/").second)
@@ -431,9 +426,22 @@ int ClangTool::run(ToolAction *Action) {
bool ProcessingFailed = false;
bool FileSkipped = false;
+ // Compute all absolute paths before we run any actions, as those will change
+ // the working directory.
+ std::vector<std::string> AbsolutePaths;
+ AbsolutePaths.reserve(SourcePaths.size());
for (const auto &SourcePath : SourcePaths) {
- std::string File(getAbsolutePath(SourcePath));
+ auto AbsPath = getAbsolutePath(*OverlayFileSystem, SourcePath);
+ if (!AbsPath) {
+ llvm::errs() << "Skipping " << SourcePath
+ << ". Error while getting an absolute path: "
+ << llvm::toString(AbsPath.takeError()) << "\n";
+ continue;
+ }
+ AbsolutePaths.push_back(std::move(*AbsPath));
+ }
+ for (llvm::StringRef File : AbsolutePaths) {
// 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
@@ -498,11 +506,6 @@ int ClangTool::run(ToolAction *Action) {
llvm::errs() << "Error while processing " << File << ".\n";
ProcessingFailed = true;
}
- // Return to the initial directory to correctly resolve next file by
- // relative path.
- if (OverlayFileSystem->setCurrentWorkingDirectory(InitialDirectory.c_str()))
- llvm::report_fatal_error("Cannot chdir into \"" +
- Twine(InitialDirectory) + "\n!");
}
}
return ProcessingFailed ? 1 : (FileSkipped ? 2 : 0);
OpenPOWER on IntegriCloud