[clang] 20b4f4f - [Driver] Add callback to Command execution
Serge Pavlov via cfe-commits
cfe-commits at lists.llvm.org
Wed Nov 4 21:23:04 PST 2020
Author: Serge Pavlov
Date: 2020-11-05T12:21:40+07:00
New Revision: 20b4f4f76030f8712824c91b5f0b0a611476f747
URL: https://github.com/llvm/llvm-project/commit/20b4f4f76030f8712824c91b5f0b0a611476f747
DIFF: https://github.com/llvm/llvm-project/commit/20b4f4f76030f8712824c91b5f0b0a611476f747.diff
LOG: [Driver] Add callback to Command execution
Summary:
Object of type `Compilation` now can keep a callback that is called
after each execution of `Command`. This must simplify adaptation of
clang in custom distributions and allow facilities like collection of
execution statistics.
Reviewers: rsmith, rjmccall, Eugene.Zelenko
Subscribers: cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D78899
Added:
Modified:
clang/include/clang/Driver/Compilation.h
clang/lib/Driver/Compilation.cpp
clang/unittests/Driver/ToolChainTest.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/Driver/Compilation.h b/clang/include/clang/Driver/Compilation.h
index 70b901434487..89a43b5b7dc0 100644
--- a/clang/include/clang/Driver/Compilation.h
+++ b/clang/include/clang/Driver/Compilation.h
@@ -115,6 +115,11 @@ class Compilation {
/// Optional redirection for stdin, stdout, stderr.
std::vector<Optional<StringRef>> Redirects;
+ /// Callback called after compilation job has been finished.
+ /// Arguments of the callback are the compilation job as an instance of
+ /// class Command and the exit status of the corresponding child process.
+ std::function<void(const Command &, int)> PostCallback;
+
/// Whether we're compiling for diagnostic purposes.
bool ForDiagnostics = false;
@@ -212,6 +217,14 @@ class Compilation {
return FailureResultFiles;
}
+ /// Installs a handler that is executed when a compilation job is finished.
+ /// The arguments of the callback specify the compilation job as an instance
+ /// of class Command and the exit status of the child process executed that
+ /// job.
+ void setPostCallback(const std::function<void(const Command &, int)> &CB) {
+ PostCallback = CB;
+ }
+
/// Returns the sysroot path.
StringRef getSysRoot() const;
diff --git a/clang/lib/Driver/Compilation.cpp b/clang/lib/Driver/Compilation.cpp
index 05ee5091396b..d33055739080 100644
--- a/clang/lib/Driver/Compilation.cpp
+++ b/clang/lib/Driver/Compilation.cpp
@@ -193,6 +193,8 @@ int Compilation::ExecuteCommand(const Command &C,
std::string Error;
bool ExecutionFailed;
int Res = C.Execute(Redirects, &Error, &ExecutionFailed);
+ if (PostCallback)
+ PostCallback(C, Res);
if (!Error.empty()) {
assert(Res && "Error string set with 0 result code!");
getDriver().Diag(diag::err_drv_command_failure) << Error;
diff --git a/clang/unittests/Driver/ToolChainTest.cpp b/clang/unittests/Driver/ToolChainTest.cpp
index 227f7c76b8a1..35060563ab97 100644
--- a/clang/unittests/Driver/ToolChainTest.cpp
+++ b/clang/unittests/Driver/ToolChainTest.cpp
@@ -289,4 +289,28 @@ TEST(ToolChainTest, CommandOutput) {
EXPECT_EQ("a.out", ExeFile);
}
+TEST(ToolChainTest, PostCallback) {
+ IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
+ IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
+ struct TestDiagnosticConsumer : public DiagnosticConsumer {};
+ DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer);
+ IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem(
+ new llvm::vfs::InMemoryFileSystem);
+
+ // The executable path must not exist.
+ Driver CCDriver("/home/test/bin/clang", "arm-linux-gnueabi", Diags,
+ "clang LLVM compiler", InMemoryFileSystem);
+ CCDriver.setCheckInputsExist(false);
+ std::unique_ptr<Compilation> CC(
+ CCDriver.BuildCompilation({"/home/test/bin/clang", "foo.cpp"}));
+ bool CallbackHasCalled = false;
+ CC->setPostCallback(
+ [&](const Command &C, int Ret) { CallbackHasCalled = true; });
+ const JobList &Jobs = CC->getJobs();
+ auto &CmdCompile = Jobs.getJobs().front();
+ const Command *FailingCmd = nullptr;
+ CC->ExecuteCommand(*CmdCompile, FailingCmd);
+ EXPECT_TRUE(CallbackHasCalled);
+}
+
} // end anonymous namespace.
More information about the cfe-commits
mailing list