Skip to content

Commit a8c9cf8

Browse files
[clang-repl] Expose CreateExecutor() and ResetExecutor() in extended Interpreter interface
1 parent aec9283 commit a8c9cf8

File tree

4 files changed

+39
-1
lines changed

4 files changed

+39
-1
lines changed

clang/include/clang/Interpreter/Interpreter.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,6 @@ class Interpreter {
9696
// An optional parser for CUDA offloading
9797
std::unique_ptr<IncrementalParser> DeviceParser;
9898

99-
llvm::Error CreateExecutor();
10099
unsigned InitPTUSize = 0;
101100

102101
// This member holds the last result of the value printing. It's a class
@@ -114,6 +113,14 @@ class Interpreter {
114113
// That's useful for testing and out-of-tree clients.
115114
Interpreter(std::unique_ptr<CompilerInstance> CI, llvm::Error &Err);
116115

116+
// Create the internal IncrementalExecutor, or re-create it after calling
117+
// ResetExecutor().
118+
llvm::Error CreateExecutor();
119+
120+
// Delete the internal IncrementalExecutor. This causes a hard shutdown of the
121+
// JIT engine. In particular, it doesn't run cleanup or destructors.
122+
void ResetExecutor();
123+
117124
// Lazily construct the RuntimeInterfaceBuilder. The provided instance will be
118125
// used for the entire lifetime of the interpreter. The default implementation
119126
// targets the in-process __clang_Interpreter runtime. Override this to use a

clang/lib/Interpreter/Interpreter.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,10 @@ Interpreter::Parse(llvm::StringRef Code) {
375375
llvm::Error Interpreter::CreateExecutor() {
376376
const clang::TargetInfo &TI =
377377
getCompilerInstance()->getASTContext().getTargetInfo();
378+
if (IncrExecutor)
379+
return llvm::make_error<llvm::StringError>("Operation failed. "
380+
"Execution engine exists",
381+
std::error_code());
378382
llvm::Error Err = llvm::Error::success();
379383
auto Executor = std::make_unique<IncrementalExecutor>(*TSCtx, Err, TI);
380384
if (!Err)
@@ -383,6 +387,8 @@ llvm::Error Interpreter::CreateExecutor() {
383387
return Err;
384388
}
385389

390+
void Interpreter::ResetExecutor() { IncrExecutor.reset(); }
391+
386392
llvm::Error Interpreter::Execute(PartialTranslationUnit &T) {
387393
assert(T.TheModule);
388394
if (!IncrExecutor) {

clang/unittests/Interpreter/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ set(LLVM_LINK_COMPONENTS
44
OrcJIT
55
Support
66
TargetParser
7+
TestingSupport
78
)
89

910
add_clang_unittest(ClangReplInterpreterTests

clang/unittests/Interpreter/InterpreterExtensionsTest.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,30 @@
2727
using namespace clang;
2828
namespace {
2929

30+
class TestCreateResetExecutor : public Interpreter {
31+
public:
32+
TestCreateResetExecutor(std::unique_ptr<CompilerInstance> CI,
33+
llvm::Error &Err)
34+
: Interpreter(std::move(CI), Err) {}
35+
36+
llvm::Error testCreateExecutor() { return Interpreter::CreateExecutor(); }
37+
38+
void resetExecutor() { Interpreter::ResetExecutor(); }
39+
};
40+
41+
TEST(InterpreterExtensionsTest, ExecutorCreateReset) {
42+
clang::IncrementalCompilerBuilder CB;
43+
llvm::Error ErrOut = llvm::Error::success();
44+
TestCreateResetExecutor Interp(cantFail(CB.CreateCpp()), ErrOut);
45+
cantFail(std::move(ErrOut));
46+
cantFail(Interp.testCreateExecutor());
47+
Interp.resetExecutor();
48+
cantFail(Interp.testCreateExecutor());
49+
EXPECT_THAT_ERROR(Interp.testCreateExecutor(),
50+
llvm::FailedWithMessage("Operation failed. "
51+
"Execution engine exists"));
52+
}
53+
3054
class RecordRuntimeIBMetrics : public Interpreter {
3155
struct NoopRuntimeInterfaceBuilder : public RuntimeInterfaceBuilder {
3256
NoopRuntimeInterfaceBuilder(Sema &S) : S(S) {}

0 commit comments

Comments
 (0)