summaryrefslogtreecommitdiffstats
path: root/clang/lib/Tooling
diff options
context:
space:
mode:
authorAlex Lorenz <arphaman@gmail.com>2019-08-30 01:25:57 +0000
committerAlex Lorenz <arphaman@gmail.com>2019-08-30 01:25:57 +0000
commitca4216abde786cf0335dcc8982a8c914a5763b83 (patch)
treee3b49d01632ff11b9844b7e74d79e713f8c9b034 /clang/lib/Tooling
parent160ed4cab4e1f25f2d6668d691577abab651f2d8 (diff)
downloadbcm5719-llvm-ca4216abde786cf0335dcc8982a8c914a5763b83.tar.gz
bcm5719-llvm-ca4216abde786cf0335dcc8982a8c914a5763b83.zip
[clang-scan-deps] NFC, refactor the DependencyScanningWorker to use a consumer
to report the dependencies to the client This will allow the scanner to report modular dependencies to the consumer. This will also allow the scanner to accept regular cc1 clang invocations, e.g. in an implementation of a libclang C API for clang-scan-deps, that I will add follow-up patches for in the future. llvm-svn: 370425
Diffstat (limited to 'clang/lib/Tooling')
-rw-r--r--clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp74
1 files changed, 39 insertions, 35 deletions
diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
index 2d49e0d794a..f6033de4618 100644
--- a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
+++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
@@ -21,21 +21,21 @@ using namespace dependencies;
namespace {
-/// Prints out all of the gathered dependencies into a string.
-class DependencyPrinter : public DependencyFileGenerator {
+/// Forwards the gatherered dependencies to the consumer.
+class DependencyConsumerForwarder : public DependencyFileGenerator {
public:
- DependencyPrinter(std::unique_ptr<DependencyOutputOptions> Opts,
- std::string &S)
- : DependencyFileGenerator(*Opts), Opts(std::move(Opts)), S(S) {}
+ DependencyConsumerForwarder(std::unique_ptr<DependencyOutputOptions> Opts,
+ DependencyConsumer &C)
+ : DependencyFileGenerator(*Opts), Opts(std::move(Opts)), C(C) {}
void finishedMainFile(DiagnosticsEngine &Diags) override {
- llvm::raw_string_ostream OS(S);
- outputDependencyFile(OS);
+ for (const auto &File : getDependencies())
+ C.handleFileDependency(*Opts, File);
}
private:
std::unique_ptr<DependencyOutputOptions> Opts;
- std::string &S;
+ DependencyConsumer &C;
};
/// A proxy file system that doesn't call `chdir` when changing the working
@@ -65,10 +65,9 @@ private:
class DependencyScanningAction : public tooling::ToolAction {
public:
DependencyScanningAction(
- StringRef WorkingDirectory, std::string &DependencyFileContents,
+ StringRef WorkingDirectory, DependencyConsumer &Consumer,
llvm::IntrusiveRefCntPtr<DependencyScanningWorkerFilesystem> DepFS)
- : WorkingDirectory(WorkingDirectory),
- DependencyFileContents(DependencyFileContents),
+ : WorkingDirectory(WorkingDirectory), Consumer(Consumer),
DepFS(std::move(DepFS)) {}
bool runInvocation(std::shared_ptr<CompilerInvocation> Invocation,
@@ -121,8 +120,9 @@ public:
// We need at least one -MT equivalent for the generator to work.
if (Opts->Targets.empty())
Opts->Targets = {"clang-scan-deps dependency"};
- Compiler.addDependencyCollector(std::make_shared<DependencyPrinter>(
- std::move(Opts), DependencyFileContents));
+ Compiler.addDependencyCollector(
+ std::make_shared<DependencyConsumerForwarder>(std::move(Opts),
+ Consumer));
auto Action = std::make_unique<PreprocessOnlyAction>();
const bool Result = Compiler.ExecuteAction(*Action);
@@ -133,8 +133,7 @@ public:
private:
StringRef WorkingDirectory;
- /// The dependency file will be written to this string.
- std::string &DependencyFileContents;
+ DependencyConsumer &Consumer;
llvm::IntrusiveRefCntPtr<DependencyScanningWorkerFilesystem> DepFS;
};
@@ -152,30 +151,35 @@ DependencyScanningWorker::DependencyScanningWorker(
Files = new FileManager(FileSystemOptions(), RealFS);
}
-llvm::Expected<std::string>
-DependencyScanningWorker::getDependencyFile(const std::string &Input,
- StringRef WorkingDirectory,
- const CompilationDatabase &CDB) {
+static llvm::Error runWithDiags(
+ DiagnosticOptions *DiagOpts,
+ llvm::function_ref<bool(DiagnosticConsumer &DC)> BodyShouldSucceed) {
// Capture the emitted diagnostics and report them to the client
// in the case of a failure.
std::string DiagnosticOutput;
llvm::raw_string_ostream DiagnosticsOS(DiagnosticOutput);
- TextDiagnosticPrinter DiagPrinter(DiagnosticsOS, DiagOpts.get());
+ TextDiagnosticPrinter DiagPrinter(DiagnosticsOS, DiagOpts);
+ if (BodyShouldSucceed(DiagPrinter))
+ return llvm::Error::success();
+ return llvm::make_error<llvm::StringError>(DiagnosticsOS.str(),
+ llvm::inconvertibleErrorCode());
+}
+
+llvm::Error DependencyScanningWorker::computeDependencies(
+ const std::string &Input, StringRef WorkingDirectory,
+ const CompilationDatabase &CDB, DependencyConsumer &Consumer) {
RealFS->setCurrentWorkingDirectory(WorkingDirectory);
- /// Create the tool that uses the underlying file system to ensure that any
- /// file system requests that are made by the driver do not go through the
- /// dependency scanning filesystem.
- tooling::ClangTool Tool(CDB, Input, PCHContainerOps, RealFS, Files);
- Tool.clearArgumentsAdjusters();
- Tool.setRestoreWorkingDir(false);
- Tool.setPrintErrorMessage(false);
- Tool.setDiagnosticConsumer(&DiagPrinter);
- std::string Output;
- DependencyScanningAction Action(WorkingDirectory, Output, DepFS);
- if (Tool.run(&Action)) {
- return llvm::make_error<llvm::StringError>(DiagnosticsOS.str(),
- llvm::inconvertibleErrorCode());
- }
- return Output;
+ return runWithDiags(DiagOpts.get(), [&](DiagnosticConsumer &DC) {
+ /// Create the tool that uses the underlying file system to ensure that any
+ /// file system requests that are made by the driver do not go through the
+ /// dependency scanning filesystem.
+ tooling::ClangTool Tool(CDB, Input, PCHContainerOps, RealFS, Files);
+ Tool.clearArgumentsAdjusters();
+ Tool.setRestoreWorkingDir(false);
+ Tool.setPrintErrorMessage(false);
+ Tool.setDiagnosticConsumer(&DC);
+ DependencyScanningAction Action(WorkingDirectory, Consumer, DepFS);
+ return !Tool.run(&Action);
+ });
}
OpenPOWER on IntegriCloud