summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Kornienko <alexfh@google.com>2014-08-27 21:36:39 +0000
committerAlexander Kornienko <alexfh@google.com>2014-08-27 21:36:39 +0000
commit9a45fac6f73f6c772fe96773ae3beab6f24c534c (patch)
tree1f1e25e525335728c9d421d9ca03bf48ce12c04a
parentdd96db2c034ce7700f4a4943bf148834adca42e7 (diff)
downloadbcm5719-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.h4
-rw-r--r--clang/lib/Tooling/Tooling.cpp93
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;
OpenPOWER on IntegriCloud