[clang] c619d4f - [clang-repl] Support destructors of global objects.

Sunho Kim via cfe-commits cfe-commits at lists.llvm.org
Thu Jul 28 10:39:06 PDT 2022


Author: Sunho Kim
Date: 2022-07-29T02:38:40+09:00
New Revision: c619d4f840dcba54751ff8c5aaafce0f173a4ad5

URL: https://github.com/llvm/llvm-project/commit/c619d4f840dcba54751ff8c5aaafce0f173a4ad5
DIFF: https://github.com/llvm/llvm-project/commit/c619d4f840dcba54751ff8c5aaafce0f173a4ad5.diff

LOG:  [clang-repl] Support destructors of global objects.

Supports destructors of global objects by properly calling jitdylib deinitialize which calls the global dtors of ir modules.

This supersedes https://reviews.llvm.org/D127945. There was an issue when calling deinitialize on windows but it got fixed by https://reviews.llvm.org/D128037.

Reviewed By: v.g.vassilev

Differential Revision: https://reviews.llvm.org/D128589

Added: 
    clang/test/Interpreter/global-dtor-win.cpp
    clang/test/Interpreter/global-dtor.cpp

Modified: 
    clang/lib/Interpreter/IncrementalExecutor.cpp
    clang/lib/Interpreter/IncrementalExecutor.h
    clang/lib/Interpreter/Interpreter.cpp
    clang/test/Interpreter/execute.cpp
    clang/tools/clang-repl/ClangRepl.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Interpreter/IncrementalExecutor.cpp b/clang/lib/Interpreter/IncrementalExecutor.cpp
index 227ab9703dc76..37d230b61f766 100644
--- a/clang/lib/Interpreter/IncrementalExecutor.cpp
+++ b/clang/lib/Interpreter/IncrementalExecutor.cpp
@@ -76,6 +76,12 @@ llvm::Error IncrementalExecutor::removeModule(PartialTranslationUnit &PTU) {
   return llvm::Error::success();
 }
 
+// Clean up the JIT instance.
+llvm::Error IncrementalExecutor::cleanUp() {
+  // This calls the global dtors of registered modules.
+  return Jit->deinitialize(Jit->getMainJITDylib());
+}
+
 llvm::Error IncrementalExecutor::runCtors() const {
   return Jit->initialize(Jit->getMainJITDylib());
 }

diff  --git a/clang/lib/Interpreter/IncrementalExecutor.h b/clang/lib/Interpreter/IncrementalExecutor.h
index 5b0f982b62ddf..54d37c76326b8 100644
--- a/clang/lib/Interpreter/IncrementalExecutor.h
+++ b/clang/lib/Interpreter/IncrementalExecutor.h
@@ -50,6 +50,7 @@ class IncrementalExecutor {
   llvm::Error addModule(PartialTranslationUnit &PTU);
   llvm::Error removeModule(PartialTranslationUnit &PTU);
   llvm::Error runCtors() const;
+  llvm::Error cleanUp();
   llvm::Expected<llvm::JITTargetAddress>
   getSymbolAddress(llvm::StringRef Name, SymbolNameKind NameKind) const;
   llvm::orc::LLJIT *getExecutionEngine() const { return Jit.get(); }

diff  --git a/clang/lib/Interpreter/Interpreter.cpp b/clang/lib/Interpreter/Interpreter.cpp
index 0191ad78581d9..bdba4ae9312ac 100644
--- a/clang/lib/Interpreter/Interpreter.cpp
+++ b/clang/lib/Interpreter/Interpreter.cpp
@@ -183,7 +183,14 @@ Interpreter::Interpreter(std::unique_ptr<CompilerInstance> CI,
                                                    *TSCtx->getContext(), Err);
 }
 
-Interpreter::~Interpreter() {}
+Interpreter::~Interpreter() {
+  if (IncrExecutor) {
+    if (llvm::Error Err = IncrExecutor->cleanUp())
+      llvm::report_fatal_error(
+          llvm::Twine("Failed to clean up IncrementalExecutor: ") +
+          toString(std::move(Err)));
+  }
+}
 
 llvm::Expected<std::unique_ptr<Interpreter>>
 Interpreter::create(std::unique_ptr<CompilerInstance> CI) {

diff  --git a/clang/test/Interpreter/execute.cpp b/clang/test/Interpreter/execute.cpp
index 0396ad82e9b36..124f6492179ec 100644
--- a/clang/test/Interpreter/execute.cpp
+++ b/clang/test/Interpreter/execute.cpp
@@ -1,3 +1,4 @@
+// clang-format off
 // RUN: clang-repl "int x = 10;" "int y=7; err;" "int y = 10;"
 // RUN: clang-repl "int i = 10;" 'extern "C" int printf(const char*,...);' \
 // RUN:            'auto r1 = printf("i = %d\n", i);' | FileCheck --check-prefix=CHECK-DRIVER %s

diff  --git a/clang/test/Interpreter/global-dtor-win.cpp b/clang/test/Interpreter/global-dtor-win.cpp
new file mode 100644
index 0000000000000..4e03298205611
--- /dev/null
+++ b/clang/test/Interpreter/global-dtor-win.cpp
@@ -0,0 +1,14 @@
+// clang-format off
+// FIXME: Merge into global-dtor.cpp when exception support arrives on windows-msvc
+// REQUIRES: host-supports-jit && windows-msvc
+//
+// Tests that a global destructor is ran in windows-msvc platform.
+//
+// RUN: cat %s | clang-repl | FileCheck %s
+
+extern "C" int printf(const char *, ... );
+
+struct D { float f = 1.0; D *m = nullptr; D(){} ~D() { printf("D[f=%f, m=0x%llx]\n", f, reinterpret_cast<unsigned long long>(m)); }} d;
+// CHECK: D[f=1.000000, m=0x0]
+
+%quit
\ No newline at end of file

diff  --git a/clang/test/Interpreter/global-dtor.cpp b/clang/test/Interpreter/global-dtor.cpp
new file mode 100644
index 0000000000000..7367fe42eb8b7
--- /dev/null
+++ b/clang/test/Interpreter/global-dtor.cpp
@@ -0,0 +1,14 @@
+// clang-format off
+// REQUIRES: host-supports-jit, host-supports-exception 
+// UNSUPPORTED: system-aix
+//
+// Tests that a global destructor is ran on platforms with gnu exception support.
+//
+// RUN: cat %s | clang-repl | FileCheck %s
+
+extern "C" int printf(const char *, ...);
+
+struct D { float f = 1.0; D *m = nullptr; D(){} ~D() { printf("D[f=%f, m=0x%llx]\n", f, reinterpret_cast<unsigned long long>(m)); }} d;
+// CHECK: D[f=1.000000, m=0x0]
+
+%quit
\ No newline at end of file

diff  --git a/clang/tools/clang-repl/ClangRepl.cpp b/clang/tools/clang-repl/ClangRepl.cpp
index 490e2feed50e1..afd604d959d43 100644
--- a/clang/tools/clang-repl/ClangRepl.cpp
+++ b/clang/tools/clang-repl/ClangRepl.cpp
@@ -108,6 +108,8 @@ int main(int argc, const char **argv) {
   ExitOnErr.setBanner("clang-repl: ");
   llvm::cl::ParseCommandLineOptions(argc, argv);
 
+  llvm::llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
+
   std::vector<const char *> ClangArgv(ClangArgs.size());
   std::transform(ClangArgs.begin(), ClangArgs.end(), ClangArgv.begin(),
                  [](const std::string &s) -> const char * { return s.data(); });
@@ -173,7 +175,5 @@ int main(int argc, const char **argv) {
   // later errors use the default handling behavior instead.
   llvm::remove_fatal_error_handler();
 
-  llvm::llvm_shutdown();
-
   return checkDiagErrors(Interp->getCompilerInstance());
 }


        


More information about the cfe-commits mailing list