diff options
author | Alexander Kornienko <alexfh@google.com> | 2014-08-27 21:36:39 +0000 |
---|---|---|
committer | Alexander Kornienko <alexfh@google.com> | 2014-08-27 21:36:39 +0000 |
commit | 9a45fac6f73f6c772fe96773ae3beab6f24c534c (patch) | |
tree | 1f1e25e525335728c9d421d9ca03bf48ce12c04a | |
parent | dd96db2c034ce7700f4a4943bf148834adca42e7 (diff) | |
download | bcm5719-llvm-9a45fac6f73f6c772fe96773ae3beab6f24c534c.tar.gz bcm5719-llvm-9a45fac6f73f6c772fe96773ae3beab6f24c534c.zip |
Query CompilationDatabase right before running each compilation.
Summary:
Query CompilationDatabase right before running each compilation. This allows
supporting compilation databases that change external state required for
successful compilation.
Reviewers: klimek, djasper
Reviewed By: djasper
Subscribers: klimek, cfe-commits
Differential Revision: http://reviews.llvm.org/D5086
llvm-svn: 216620
-rw-r--r-- | clang/include/clang/Tooling/Tooling.h | 4 | ||||
-rw-r--r-- | clang/lib/Tooling/Tooling.cpp | 93 |
2 files changed, 46 insertions, 51 deletions
diff --git a/clang/include/clang/Tooling/Tooling.h b/clang/include/clang/Tooling/Tooling.h index fb9178abcc4..6f0d5796880 100644 --- a/clang/include/clang/Tooling/Tooling.h +++ b/clang/include/clang/Tooling/Tooling.h @@ -293,8 +293,8 @@ class ClangTool { FileManager &getFiles() { return *Files; } private: - // We store compile commands as pair (file name, compile command). - std::vector< std::pair<std::string, CompileCommand> > CompileCommands; + const CompilationDatabase &Compilations; + std::vector<std::string> SourcePaths; llvm::IntrusiveRefCntPtr<FileManager> Files; // Contains a list of pairs (<file name>, <file content>). diff --git a/clang/lib/Tooling/Tooling.cpp b/clang/lib/Tooling/Tooling.cpp index cf8536e234f..e014bfd34ac 100644 --- a/clang/lib/Tooling/Tooling.cpp +++ b/clang/lib/Tooling/Tooling.cpp @@ -273,28 +273,10 @@ bool FrontendActionFactory::runInvocation(CompilerInvocation *Invocation, ClangTool::ClangTool(const CompilationDatabase &Compilations, ArrayRef<std::string> SourcePaths) - : Files(new FileManager(FileSystemOptions())), DiagConsumer(nullptr) { + : Compilations(Compilations), SourcePaths(SourcePaths), + Files(new FileManager(FileSystemOptions())), DiagConsumer(nullptr) { ArgsAdjusters.push_back(new ClangStripOutputAdjuster()); ArgsAdjusters.push_back(new ClangSyntaxOnlyAdjuster()); - for (const auto &SourcePath : SourcePaths) { - std::string File(getAbsolutePath(SourcePath)); - - std::vector<CompileCommand> CompileCommandsForFile = - Compilations.getCompileCommands(File); - if (!CompileCommandsForFile.empty()) { - for (CompileCommand &CompileCommand : CompileCommandsForFile) { - CompileCommands.push_back( - std::make_pair(File, std::move(CompileCommand))); - } - } else { - // FIXME: There are two use cases here: doing a fuzzy - // "find . -name '*.cc' |xargs tool" match, where as a user I don't care - // about the .cc files that were not found, and the use case where I - // specify all files I want to run over explicitly, where this should - // be an error. We'll want to add an option for this. - llvm::errs() << "Skipping " << File << ". Compile command not found.\n"; - } - } } void ClangTool::setDiagnosticConsumer(DiagnosticConsumer *D) { @@ -333,36 +315,49 @@ int ClangTool::run(ToolAction *Action) { llvm::sys::fs::getMainExecutable("clang_tool", &StaticSymbol); bool ProcessingFailed = false; - for (const auto &Command : CompileCommands) { - // 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(Command.second.Directory.c_str())) - llvm::report_fatal_error("Cannot chdir into \"" + - Twine(Command.second.Directory) + "\n!"); - std::vector<std::string> CommandLine = Command.second.CommandLine; - for (ArgumentsAdjuster *Adjuster : ArgsAdjusters) - CommandLine = Adjuster->Adjust(CommandLine); - assert(!CommandLine.empty()); - CommandLine[0] = MainExecutable; - // FIXME: We need a callback mechanism for the tool writer to output a - // customized message for each file. - DEBUG({ - llvm::dbgs() << "Processing: " << Command.first << ".\n"; - }); - ToolInvocation Invocation(std::move(CommandLine), Action, Files.get()); - Invocation.setDiagnosticConsumer(DiagConsumer); - for (const auto &MappedFile : MappedFileContents) { - Invocation.mapVirtualFile(MappedFile.first, MappedFile.second); + for (const auto &SourcePath : SourcePaths) { + std::string File(getAbsolutePath(SourcePath)); + + std::vector<CompileCommand> CompileCommandsForFile = + Compilations.getCompileCommands(File); + if (CompileCommandsForFile.empty()) { + // FIXME: There are two use cases here: doing a fuzzy + // "find . -name '*.cc' |xargs tool" match, where as a user I don't care + // about the .cc files that were not found, and the use case where I + // specify all files I want to run over explicitly, where this should + // be an error. We'll want to add an option for this. + llvm::errs() << "Skipping " << File << ". Compile command not found.\n"; + continue; } - if (!Invocation.run()) { - // FIXME: Diagnostics should be used instead. - llvm::errs() << "Error while processing " << Command.first << ".\n"; - ProcessingFailed = true; + for (CompileCommand &CompileCommand : CompileCommandsForFile) { + // 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(CompileCommand.Directory.c_str())) + llvm::report_fatal_error("Cannot chdir into \"" + + Twine(CompileCommand.Directory) + "\n!"); + std::vector<std::string> CommandLine = CompileCommand.CommandLine; + for (ArgumentsAdjuster *Adjuster : ArgsAdjusters) + CommandLine = Adjuster->Adjust(CommandLine); + assert(!CommandLine.empty()); + CommandLine[0] = MainExecutable; + // FIXME: We need a callback mechanism for the tool writer to output a + // customized message for each file. + DEBUG({ llvm::dbgs() << "Processing: " << File << ".\n"; }); + ToolInvocation Invocation(std::move(CommandLine), Action, Files.get()); + Invocation.setDiagnosticConsumer(DiagConsumer); + 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 ProcessingFailed ? 1 : 0; |