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<CompileCommand> CompileCommandsForFile =
Compilations.getCompileCommands(File);
if (CompileCommandsForFile.empty()) {
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;