https://github.com/anutosh491 updated 
https://github.com/llvm/llvm-project/pull/230047

>From e2aa67d32451f356b0866b679f3a1c8e5fc876fa Mon Sep 17 00:00:00 2001
From: anutosh491 <[email protected]>
Date: Thu, 8 Oct 2026 15:18:59 +0530
Subject: [PATCH 1/4] [clang-repl] Split incremental executor builders by
 backend

---
 .../clang/Interpreter/IncrementalExecutor.h   | 55 ++++----------
 .../OrcIncrementalExecutorBuilder.h           | 73 +++++++++++++++++++
 clang/lib/Interpreter/CMakeLists.txt          |  3 +-
 .../IncrementalExecutorBuilder.cpp            | 27 +++++++
 clang/lib/Interpreter/Interpreter.cpp         |  2 +-
 ....cpp => OrcIncrementalExecutorBuilder.cpp} | 25 ++++---
 clang/lib/Interpreter/Wasm.cpp                | 26 ++-----
 clang/lib/Interpreter/Wasm.h                  |  7 ++
 clang/tools/clang-repl/ClangRepl.cpp          |  4 +-
 .../Interpreter/InterpreterExtensionsTest.cpp |  5 +-
 .../OutOfProcessInterpreterTests.cpp          |  4 +-
 11 files changed, 154 insertions(+), 77 deletions(-)
 create mode 100644 
clang/include/clang/Interpreter/OrcIncrementalExecutorBuilder.h
 create mode 100644 clang/lib/Interpreter/IncrementalExecutorBuilder.cpp
 rename clang/lib/Interpreter/{IncrementalExecutor.cpp => 
OrcIncrementalExecutorBuilder.cpp} (95%)

diff --git a/clang/include/clang/Interpreter/IncrementalExecutor.h 
b/clang/include/clang/Interpreter/IncrementalExecutor.h
index 2e037d1f090e5..bb49e673cb529 100644
--- a/clang/include/clang/Interpreter/IncrementalExecutor.h
+++ b/clang/include/clang/Interpreter/IncrementalExecutor.h
@@ -13,13 +13,15 @@
 #ifndef LLVM_CLANG_LIB_INTERPRETER_INCREMENTALEXECUTOR_H
 #define LLVM_CLANG_LIB_INTERPRETER_INCREMENTALEXECUTOR_H
 
-#include "llvm/Support/CodeGen.h"
 #include "llvm/Support/Error.h"
 
+#include <memory>
+#include <string>
+#include <vector>
+
 namespace llvm {
 namespace orc {
 class ExecutorAddr;
-class LLJITBuilder;
 class ThreadSafeContext;
 } // namespace orc
 } // namespace llvm
@@ -27,53 +29,28 @@ class ThreadSafeContext;
 namespace clang {
 class IncrementalExecutor;
 class TargetInfo;
-namespace driver {
-class Compilation;
-} // namespace driver
 
+/// Common configuration and interface for incremental executor builders.
 class IncrementalExecutorBuilder {
 public:
-  /// Indicates whether out-of-process JIT execution is enabled.
-  bool IsOutOfProcess = false;
-  /// Path to the out-of-process JIT executor.
-  std::string OOPExecutor = "";
-  std::string OOPExecutorConnect = "";
-  /// Indicates whether to use shared memory for communication.
-  bool UseSharedMemory = false;
-  /// Representing the slab allocation size for memory management in kb.
-  unsigned SlabAllocateSize = 0;
-  /// Path to the ORC runtime library.
-  std::string OrcRuntimePath = "";
-  /// PID of the out-of-process JIT executor.
-  uint32_t ExecutorPID = 0;
-  /// Custom lambda to be executed inside child process/executor
-  std::function<void()> CustomizeFork = nullptr;
-  /// An optional code model to provide to the JITTargetMachineBuilder
-  std::optional<llvm::CodeModel::Model> CM = std::nullopt;
-  /// An optional external IncrementalExecutor
+  /// An optional external IncrementalExecutor.
   std::unique_ptr<IncrementalExecutor> IE;
-  /// mllvm args from the frontend; on wasm these are re-applied after each
-  /// lldMain call because lld resets all cl options for test-isolation
-  /// purposes.
+  /// Frontend -mllvm arguments for backends that need to restore LLVM options.
   std::vector<std::string> LLVMArgs;
-#ifndef __EMSCRIPTEN__
-  /// An optional external orc jit builder
-  std::unique_ptr<llvm::orc::LLJITBuilder> JITBuilder;
-#endif
-  /// A default callback that can be used in the IncrementalCompilerBuilder to
-  /// retrieve the path to the orc runtime.
-  std::function<llvm::Error(const driver::Compilation &)>
-      UpdateOrcRuntimePathCB = [this](const driver::Compilation &C) {
-        return UpdateOrcRuntimePath(C);
-      };
-
-  ~IncrementalExecutorBuilder();
 
+  virtual ~IncrementalExecutorBuilder();
+
+  /// Create the default builder for the platform clangInterpreter is built 
for.
+  static std::unique_ptr<IncrementalExecutorBuilder> createDefault();
+
+  /// Return the supplied executor, or create one using the selected backend.
   llvm::Expected<std::unique_ptr<IncrementalExecutor>>
   create(llvm::orc::ThreadSafeContext &TSC, const clang::TargetInfo &TI);
 
 private:
-  llvm::Error UpdateOrcRuntimePath(const driver::Compilation &C);
+  virtual llvm::Expected<std::unique_ptr<IncrementalExecutor>>
+  createExecutor(llvm::orc::ThreadSafeContext &TSC,
+                 const clang::TargetInfo &TI) = 0;
 };
 
 struct PartialTranslationUnit;
diff --git a/clang/include/clang/Interpreter/OrcIncrementalExecutorBuilder.h 
b/clang/include/clang/Interpreter/OrcIncrementalExecutorBuilder.h
new file mode 100644
index 0000000000000..d443f69f65710
--- /dev/null
+++ b/clang/include/clang/Interpreter/OrcIncrementalExecutorBuilder.h
@@ -0,0 +1,73 @@
+//===-- OrcIncrementalExecutorBuilder.h - ORC Builder -----------*- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the builder for ORC incremental execution.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_INTERPRETER_ORCINCREMENTALEXECUTORBUILDER_H
+#define LLVM_CLANG_INTERPRETER_ORCINCREMENTALEXECUTORBUILDER_H
+
+#include "clang/Interpreter/IncrementalExecutor.h"
+#include "llvm/Support/CodeGen.h"
+
+#include <cstdint>
+#include <functional>
+#include <optional>
+
+namespace llvm::orc {
+class LLJITBuilder;
+}
+
+namespace clang {
+namespace driver {
+class Compilation;
+}
+
+/// Configuration for in-process and out-of-process ORC execution.
+class OrcIncrementalExecutorBuilder : public IncrementalExecutorBuilder {
+public:
+  /// Indicates whether out-of-process JIT execution is enabled.
+  bool IsOutOfProcess = false;
+  /// Path to the out-of-process JIT executor.
+  std::string OOPExecutor = "";
+  std::string OOPExecutorConnect = "";
+  /// Indicates whether to use shared memory for communication.
+  bool UseSharedMemory = false;
+  /// Representing the slab allocation size for memory management in kb.
+  unsigned SlabAllocateSize = 0;
+  /// Path to the ORC runtime library.
+  std::string OrcRuntimePath = "";
+  /// PID of the out-of-process JIT executor.
+  uint32_t ExecutorPID = 0;
+  /// Custom lambda to be executed inside child process/executor
+  std::function<void()> CustomizeFork = nullptr;
+  /// An optional code model to provide to the JITTargetMachineBuilder
+  std::optional<llvm::CodeModel::Model> CM = std::nullopt;
+  /// An optional external ORC JIT builder.
+  std::unique_ptr<llvm::orc::LLJITBuilder> JITBuilder;
+  /// A default callback that can be used in the IncrementalCompilerBuilder to
+  /// retrieve the path to the orc runtime.
+  std::function<llvm::Error(const driver::Compilation &)>
+      UpdateOrcRuntimePathCB = [this](const driver::Compilation &C) {
+        return UpdateOrcRuntimePath(C);
+      };
+
+  OrcIncrementalExecutorBuilder();
+  ~OrcIncrementalExecutorBuilder() override;
+
+private:
+  llvm::Expected<std::unique_ptr<IncrementalExecutor>>
+  createExecutor(llvm::orc::ThreadSafeContext &TSC,
+                 const clang::TargetInfo &TI) override;
+  llvm::Error UpdateOrcRuntimePath(const driver::Compilation &C);
+};
+
+} // namespace clang
+
+#endif // LLVM_CLANG_INTERPRETER_ORCINCREMENTALEXECUTORBUILDER_H
diff --git a/clang/lib/Interpreter/CMakeLists.txt 
b/clang/lib/Interpreter/CMakeLists.txt
index d097e11a75970..5e2937a2e7dcb 100644
--- a/clang/lib/Interpreter/CMakeLists.txt
+++ b/clang/lib/Interpreter/CMakeLists.txt
@@ -23,7 +23,7 @@ else()
     OrcTargetProcess
     )
   set(EXECUTOR_SOURCES
-    IncrementalExecutor.cpp
+    OrcIncrementalExecutorBuilder.cpp
     OrcIncrementalExecutor.cpp
     )
 endif()
@@ -32,6 +32,7 @@ add_clang_library(clangInterpreter
   DeviceOffload.cpp
   CodeCompletion.cpp
   IncrementalAction.cpp
+  IncrementalExecutorBuilder.cpp
   IncrementalParser.cpp
   Interpreter.cpp
   InterpreterValuePrinter.cpp
diff --git a/clang/lib/Interpreter/IncrementalExecutorBuilder.cpp 
b/clang/lib/Interpreter/IncrementalExecutorBuilder.cpp
new file mode 100644
index 0000000000000..f1110ebca99af
--- /dev/null
+++ b/clang/lib/Interpreter/IncrementalExecutorBuilder.cpp
@@ -0,0 +1,27 @@
+//===-- IncrementalExecutorBuilder.cpp - Executor Builder ------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This implements the common incremental executor builder.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Interpreter/IncrementalExecutor.h"
+
+namespace clang {
+
+IncrementalExecutorBuilder::~IncrementalExecutorBuilder() = default;
+
+llvm::Expected<std::unique_ptr<IncrementalExecutor>>
+IncrementalExecutorBuilder::create(llvm::orc::ThreadSafeContext &TSC,
+                                   const clang::TargetInfo &TI) {
+  if (IE)
+    return std::move(IE);
+  return createExecutor(TSC, TI);
+}
+
+} // namespace clang
diff --git a/clang/lib/Interpreter/Interpreter.cpp 
b/clang/lib/Interpreter/Interpreter.cpp
index a8e54d62864b5..1463eb75f4b4f 100644
--- a/clang/lib/Interpreter/Interpreter.cpp
+++ b/clang/lib/Interpreter/Interpreter.cpp
@@ -605,7 +605,7 @@ llvm::Error Interpreter::CreateExecutor() {
                                                std::error_code());
 
   if (!IncrExecutorBuilder)
-    IncrExecutorBuilder = std::make_unique<IncrementalExecutorBuilder>();
+    IncrExecutorBuilder = IncrementalExecutorBuilder::createDefault();
 
   // Propagate mllvm args so the wasm executor can restore them after each
   // lldMain invocation (which resets all cl options for test isolation).
diff --git a/clang/lib/Interpreter/IncrementalExecutor.cpp 
b/clang/lib/Interpreter/OrcIncrementalExecutorBuilder.cpp
similarity index 95%
rename from clang/lib/Interpreter/IncrementalExecutor.cpp
rename to clang/lib/Interpreter/OrcIncrementalExecutorBuilder.cpp
index db805bb4219a4..59e375a85fab7 100644
--- a/clang/lib/Interpreter/IncrementalExecutor.cpp
+++ b/clang/lib/Interpreter/OrcIncrementalExecutorBuilder.cpp
@@ -1,4 +1,4 @@
-//===--- IncrementalExecutor.cpp - Incremental Execution --------*- C++ 
-*-===//
+//===-- OrcIncrementalExecutorBuilder.cpp - ORC Builder --------*- C++ -*-===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -6,11 +6,11 @@
 //
 
//===----------------------------------------------------------------------===//
 //
-// This has the implementation of the base facilities for incremental 
execution.
+// This implements the builder for ORC incremental execution.
 //
 
//===----------------------------------------------------------------------===//
 
-#include "clang/Interpreter/IncrementalExecutor.h"
+#include "clang/Interpreter/OrcIncrementalExecutorBuilder.h"
 #include "OrcIncrementalExecutor.h"
 
 #include "clang/Basic/TargetInfo.h"
@@ -81,7 +81,13 @@ static void *getEmuTLSGetAddressPtr() { return nullptr; }
 #endif
 
 namespace clang {
-IncrementalExecutorBuilder::~IncrementalExecutorBuilder() = default;
+OrcIncrementalExecutorBuilder::OrcIncrementalExecutorBuilder() = default;
+OrcIncrementalExecutorBuilder::~OrcIncrementalExecutorBuilder() = default;
+
+std::unique_ptr<IncrementalExecutorBuilder>
+IncrementalExecutorBuilder::createDefault() {
+  return std::make_unique<OrcIncrementalExecutorBuilder>();
+}
 
 static llvm::Expected<llvm::orc::JITTargetMachineBuilder>
 createJITTargetMachineBuilder(const llvm::Triple &TT) {
@@ -321,7 +327,8 @@ 
createLLJITBuilder(std::unique_ptr<llvm::orc::ExecutorProcessControl> EPC,
 
 static llvm::Expected<
     std::pair<std::unique_ptr<llvm::orc::LLJITBuilder>, uint32_t>>
-outOfProcessJITBuilder(const IncrementalExecutorBuilder &IncrExecutorBuilder) {
+outOfProcessJITBuilder(
+    const OrcIncrementalExecutorBuilder &IncrExecutorBuilder) {
   std::unique_ptr<llvm::orc::ExecutorProcessControl> EPC;
   uint32_t childPid = -1;
   if (!IncrExecutorBuilder.OOPExecutor.empty()) {
@@ -367,10 +374,8 @@ outOfProcessJITBuilder(const IncrementalExecutorBuilder 
&IncrExecutorBuilder) {
 }
 
 llvm::Expected<std::unique_ptr<IncrementalExecutor>>
-IncrementalExecutorBuilder::create(llvm::orc::ThreadSafeContext &TSC,
-                                   const clang::TargetInfo &TI) {
-  if (IE)
-    return std::move(IE);
+OrcIncrementalExecutorBuilder::createExecutor(llvm::orc::ThreadSafeContext 
&TSC,
+                                              const clang::TargetInfo &TI) {
   llvm::Triple TT = TI.getTriple();
   if (!TT.isOSWindows() && IsOutOfProcess) {
     if (!JITBuilder) {
@@ -433,7 +438,7 @@ 
IncrementalExecutorBuilder::create(llvm::orc::ThreadSafeContext &TSC,
   return std::move(Executor);
 }
 
-llvm::Error IncrementalExecutorBuilder::UpdateOrcRuntimePath(
+llvm::Error OrcIncrementalExecutorBuilder::UpdateOrcRuntimePath(
     const clang::driver::Compilation &C) {
   if (!IsOutOfProcess)
     return llvm::Error::success();
diff --git a/clang/lib/Interpreter/Wasm.cpp b/clang/lib/Interpreter/Wasm.cpp
index dbafaae85b556..9351ab642c707 100644
--- a/clang/lib/Interpreter/Wasm.cpp
+++ b/clang/lib/Interpreter/Wasm.cpp
@@ -62,19 +62,14 @@ bool link(llvm::ArrayRef<const char *> args, 
llvm::raw_ostream &stdoutOS,
 
 namespace clang {
 
-IncrementalExecutorBuilder::~IncrementalExecutorBuilder() = default;
+std::unique_ptr<IncrementalExecutorBuilder>
+IncrementalExecutorBuilder::createDefault() {
+  return std::make_unique<WasmIncrementalExecutorBuilder>();
+}
 
 llvm::Expected<std::unique_ptr<IncrementalExecutor>>
-IncrementalExecutorBuilder::create(llvm::orc::ThreadSafeContext &TSC,
-                                   const clang::TargetInfo &TI) {
-  if (IE)
-    return std::move(IE);
-
-  if (IsOutOfProcess)
-    return llvm::createStringError(llvm::inconvertibleErrorCode(),
-                                   "Out-of-process execution is not supported "
-                                   "by the WebAssembly executor");
-
+WasmIncrementalExecutorBuilder::createExecutor(
+    llvm::orc::ThreadSafeContext &TSC, const clang::TargetInfo &TI) {
   llvm::Error Err = llvm::Error::success();
   std::unique_ptr<IncrementalExecutor> Executor =
       std::make_unique<WasmIncrementalExecutor>(Err, LLVMArgs);
@@ -83,15 +78,6 @@ 
IncrementalExecutorBuilder::create(llvm::orc::ThreadSafeContext &TSC,
   return std::move(Executor);
 }
 
-llvm::Error IncrementalExecutorBuilder::UpdateOrcRuntimePath(
-    const clang::driver::Compilation &C) {
-  if (IsOutOfProcess)
-    return llvm::createStringError(llvm::inconvertibleErrorCode(),
-                                   "Out-of-process execution is not supported "
-                                   "by the WebAssembly executor");
-  return llvm::Error::success();
-}
-
 WasmIncrementalExecutor::WasmIncrementalExecutor(
     llvm::Error &Err, std::vector<std::string> LLVMArgs)
     : StoredLLVMArgs(std::move(LLVMArgs)) {
diff --git a/clang/lib/Interpreter/Wasm.h b/clang/lib/Interpreter/Wasm.h
index 6340393dc6b9b..3adf82cdacb7c 100644
--- a/clang/lib/Interpreter/Wasm.h
+++ b/clang/lib/Interpreter/Wasm.h
@@ -24,6 +24,13 @@
 
 namespace clang {
 
+class WasmIncrementalExecutorBuilder : public IncrementalExecutorBuilder {
+private:
+  llvm::Expected<std::unique_ptr<IncrementalExecutor>>
+  createExecutor(llvm::orc::ThreadSafeContext &TSC,
+                 const clang::TargetInfo &TI) override;
+};
+
 class WasmIncrementalExecutor : public IncrementalExecutor {
 public:
   WasmIncrementalExecutor(llvm::Error &Err, std::vector<std::string> LLVMArgs);
diff --git a/clang/tools/clang-repl/ClangRepl.cpp 
b/clang/tools/clang-repl/ClangRepl.cpp
index c9873540a5d66..8957a74ce17cf 100644
--- a/clang/tools/clang-repl/ClangRepl.cpp
+++ b/clang/tools/clang-repl/ClangRepl.cpp
@@ -16,8 +16,8 @@
 #include "clang/Config/config.h"
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Interpreter/CodeCompletion.h"
-#include "clang/Interpreter/IncrementalExecutor.h"
 #include "clang/Interpreter/Interpreter.h"
+#include "clang/Interpreter/OrcIncrementalExecutorBuilder.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Sema/Sema.h"
 
@@ -294,7 +294,7 @@ int main(int argc, const char **argv) {
   clang::IncrementalCompilerBuilder CB;
   CB.SetCompilerArgs(ClangArgv);
 
-  auto IEB = std::make_unique<clang::IncrementalExecutorBuilder>();
+  auto IEB = std::make_unique<clang::OrcIncrementalExecutorBuilder>();
   IEB->IsOutOfProcess = !OOPExecutor.empty() || !OOPExecutorConnect.empty();
   IEB->OOPExecutor = OOPExecutor;
   if (!OrcRuntimePath.empty())
diff --git a/clang/unittests/Interpreter/InterpreterExtensionsTest.cpp 
b/clang/unittests/Interpreter/InterpreterExtensionsTest.cpp
index 642869e124b8b..f1cd3b38fbfd9 100644
--- a/clang/unittests/Interpreter/InterpreterExtensionsTest.cpp
+++ b/clang/unittests/Interpreter/InterpreterExtensionsTest.cpp
@@ -13,6 +13,7 @@
 #include "InterpreterTestFixture.h"
 
 #include "clang/Interpreter/Interpreter.h"
+#include "clang/Interpreter/OrcIncrementalExecutorBuilder.h"
 
 #include "clang/AST/Expr.h"
 #include "clang/Frontend/CompilerInstance.h"
@@ -125,7 +126,7 @@ TEST_F(InterpreterExtensionsTest, CustomCrossJIT) {
     JIT = &J;
     return llvm::Error::success();
   });
-  auto IEB = std::make_unique<IncrementalExecutorBuilder>();
+  auto IEB = std::make_unique<OrcIncrementalExecutorBuilder>();
   IEB->JITBuilder = std::move(JB);
   llvm::Error ErrOut = llvm::Error::success();
   CustomJBInterpreter Interp(std::move(CI), ErrOut, std::move(IEB));
@@ -181,7 +182,7 @@ TEST_F(InterpreterExtensionsTest, 
CustomIncrementalExecutor) {
   };
 
   // Prepare a builder that hands out our recording executor.
-  auto B = std::make_unique<IncrementalExecutorBuilder>();
+  auto B = IncrementalExecutorBuilder::createDefault();
   B->IE = std::make_unique<RecordingIncrementalExecutor>();
 
   IncrementalCompilerBuilder CB;
diff --git a/clang/unittests/Interpreter/OutOfProcessInterpreterTests.cpp 
b/clang/unittests/Interpreter/OutOfProcessInterpreterTests.cpp
index 3684e7e8148fa..f67ad02d918c6 100644
--- a/clang/unittests/Interpreter/OutOfProcessInterpreterTests.cpp
+++ b/clang/unittests/Interpreter/OutOfProcessInterpreterTests.cpp
@@ -18,8 +18,8 @@
 #include "clang/AST/Mangle.h"
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Frontend/TextDiagnosticPrinter.h"
-#include "clang/Interpreter/IncrementalExecutor.h"
 #include "clang/Interpreter/Interpreter.h"
+#include "clang/Interpreter/OrcIncrementalExecutorBuilder.h"
 #include "clang/Interpreter/Value.h"
 #include "clang/Sema/Lookup.h"
 #include "clang/Sema/Sema.h"
@@ -115,7 +115,7 @@ 
createInterpreterWithRemoteExecution(std::shared_ptr<IOContext> io_ctx,
   Args ClangArgs = {"-Xclang", "-emit-llvm-only"};
   llvm::append_range(ClangArgs, ExtraArgs);
 
-  auto Config = std::make_unique<IncrementalExecutorBuilder>();
+  auto Config = std::make_unique<OrcIncrementalExecutorBuilder>();
 
   Config->IsOutOfProcess = true;
   Config->OOPExecutor = getExecutorPath();

>From 4c498c5d71fdc8cbc6f03edd446c30310fca15f6 Mon Sep 17 00:00:00 2001
From: anutosh491 <[email protected]>
Date: Thu, 8 Oct 2026 18:34:53 +0530
Subject: [PATCH 2/4] [clang-repl] Fix executor builder selection for
 Emscripten

---
 .../clang/Interpreter/IncrementalExecutor.h   |  1 +
 clang/tools/clang-repl/ClangRepl.cpp          | 20 +++++++++++++------
 2 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/clang/include/clang/Interpreter/IncrementalExecutor.h 
b/clang/include/clang/Interpreter/IncrementalExecutor.h
index bb49e673cb529..815e2b2d9bf5c 100644
--- a/clang/include/clang/Interpreter/IncrementalExecutor.h
+++ b/clang/include/clang/Interpreter/IncrementalExecutor.h
@@ -41,6 +41,7 @@ class IncrementalExecutorBuilder {
   virtual ~IncrementalExecutorBuilder();
 
   /// Create the default builder for the platform clangInterpreter is built 
for.
+  /// The selected backend provides this definition.
   static std::unique_ptr<IncrementalExecutorBuilder> createDefault();
 
   /// Return the supplied executor, or create one using the selected backend.
diff --git a/clang/tools/clang-repl/ClangRepl.cpp 
b/clang/tools/clang-repl/ClangRepl.cpp
index 8957a74ce17cf..eadb8b2e72368 100644
--- a/clang/tools/clang-repl/ClangRepl.cpp
+++ b/clang/tools/clang-repl/ClangRepl.cpp
@@ -108,7 +108,10 @@ static llvm::Error sanitizeOopArguments(const char *ArgV0) 
{
       (OOPExecutor.getNumOccurrences() ||
        OOPExecutorConnect.getNumOccurrences()))
     return llvm::make_error<llvm::StringError>(
-        "Out-of-process execution is only supported on Unix platforms",
+        SystemTriple.isOSEmscripten()
+            ? "Out-of-process execution is not supported by the WebAssembly "
+              "executor"
+            : "Out-of-process execution is only supported on Unix platforms",
         llvm::inconvertibleErrorCode());
 
   // If -slab-allocate is passed, check that we're not trying to use it in
@@ -294,6 +297,15 @@ int main(int argc, const char **argv) {
   clang::IncrementalCompilerBuilder CB;
   CB.SetCompilerArgs(ClangArgv);
 
+  auto SizeOrErr = getSlabAllocSize(SlabAllocateSizeString);
+  if (!SizeOrErr) {
+    llvm::logAllUnhandledErrors(SizeOrErr.takeError(), llvm::errs(), "error: 
");
+    return EXIT_FAILURE;
+  }
+
+#ifdef __EMSCRIPTEN__
+  auto IEB = clang::IncrementalExecutorBuilder::createDefault();
+#else
   auto IEB = std::make_unique<clang::OrcIncrementalExecutorBuilder>();
   IEB->IsOutOfProcess = !OOPExecutor.empty() || !OOPExecutorConnect.empty();
   IEB->OOPExecutor = OOPExecutor;
@@ -302,13 +314,9 @@ int main(int argc, const char **argv) {
   else
     CB.SetDriverCompilationCallback(IEB->UpdateOrcRuntimePathCB);
 
-  auto SizeOrErr = getSlabAllocSize(SlabAllocateSizeString);
-  if (!SizeOrErr) {
-    llvm::logAllUnhandledErrors(SizeOrErr.takeError(), llvm::errs(), "error: 
");
-    return EXIT_FAILURE;
-  }
   IEB->SlabAllocateSize = *SizeOrErr;
   IEB->UseSharedMemory = UseSharedMemory;
+#endif
 
   std::unique_ptr<clang::CompilerInstance> DeviceCI;
   if (CudaEnabled) {

>From 8f322b5f4154026ca8613f994742ee2656a063c3 Mon Sep 17 00:00:00 2001
From: anutosh491 <[email protected]>
Date: Thu, 8 Oct 2026 20:28:23 +0530
Subject: [PATCH 3/4] [clang-repl] Build Emscripten tool without ORC
 dependencies

---
 clang/tools/clang-repl/CMakeLists.txt | 17 +++++++++++++++--
 clang/tools/clang-repl/ClangRepl.cpp  | 11 +++++++++++
 2 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/clang/tools/clang-repl/CMakeLists.txt 
b/clang/tools/clang-repl/CMakeLists.txt
index c3d14ceb79792..bd66fa5aeb3d4 100644
--- a/clang/tools/clang-repl/CMakeLists.txt
+++ b/clang/tools/clang-repl/CMakeLists.txt
@@ -3,18 +3,31 @@ set( LLVM_LINK_COMPONENTS
   Core
   LineEditor
   Option
-  OrcJIT
-  OrcShared
   Support
   TargetParser
   )
 
+if(NOT EMSCRIPTEN)
+  list(APPEND LLVM_LINK_COMPONENTS OrcJIT OrcShared)
+endif()
+
 add_clang_tool(clang-repl
   ClangRepl.cpp
 
   EXPORT_SYMBOLS
   )
 
+if(EMSCRIPTEN)
+  # Incremental modules use dlopen and resolve symbols from the tool.
+  target_link_options(clang-repl PRIVATE
+    "-fwasm-exceptions"
+    "SHELL:-s MAIN_MODULE=1"
+    "LINKER:--export=__clang_Interpreter_SetValueWithAlloc"
+    "LINKER:--export=__clang_Interpreter_SetValueNoAlloc"
+    "LINKER:--export=_ZnwmPv26__clang_Interpreter_NewTag"
+  )
+endif()
+
 if(MSVC)
   set_target_properties(clang-repl PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS 1)
 
diff --git a/clang/tools/clang-repl/ClangRepl.cpp 
b/clang/tools/clang-repl/ClangRepl.cpp
index eadb8b2e72368..a5165109c65eb 100644
--- a/clang/tools/clang-repl/ClangRepl.cpp
+++ b/clang/tools/clang-repl/ClangRepl.cpp
@@ -276,6 +276,16 @@ int main(int argc, const char **argv) {
   llvm::InitializeAllAsmPrinters();
   llvm::InitializeAllAsmParsers();
 
+#ifdef __EMSCRIPTEN__
+  if (OptHostSupportsJit) {
+    llvm::outs() << "false\n";
+    return 0;
+  } else if (OptHostJitTriple) {
+    llvm::outs() << llvm::Triple::normalize(llvm::sys::getProcessTriple())
+                 << '\n';
+    return 0;
+  }
+#else
   if (OptHostSupportsJit) {
     auto J = llvm::orc::LLJITBuilder().create();
     if (J)
@@ -291,6 +301,7 @@ int main(int argc, const char **argv) {
     llvm::outs() << T.normalize() << '\n';
     return 0;
   }
+#endif
 
   ExitOnErr(sanitizeOopArguments(argv[0]));
 

>From d35715db7f04e23beb5e89d11248290f8b7493f6 Mon Sep 17 00:00:00 2001
From: anutosh491 <[email protected]>
Date: Thu, 8 Oct 2026 21:25:27 +0530
Subject: [PATCH 4/4] [clang-repl] Hide backend setup behind executor builders

---
 .../clang/Interpreter/IncrementalExecutor.h   | 21 ++++++++
 .../OrcIncrementalExecutorBuilder.h           |  5 ++
 .../OrcIncrementalExecutorBuilder.cpp         | 31 ++++++++++++
 clang/lib/Interpreter/Wasm.cpp                | 15 ++++++
 clang/lib/Interpreter/Wasm.h                  |  6 +++
 clang/tools/clang-repl/CMakeLists.txt         |  4 --
 clang/tools/clang-repl/ClangRepl.cpp          | 49 +++++--------------
 7 files changed, 89 insertions(+), 42 deletions(-)

diff --git a/clang/include/clang/Interpreter/IncrementalExecutor.h 
b/clang/include/clang/Interpreter/IncrementalExecutor.h
index 815e2b2d9bf5c..6615355b798c1 100644
--- a/clang/include/clang/Interpreter/IncrementalExecutor.h
+++ b/clang/include/clang/Interpreter/IncrementalExecutor.h
@@ -20,6 +20,7 @@
 #include <vector>
 
 namespace llvm {
+class Triple;
 namespace orc {
 class ExecutorAddr;
 class ThreadSafeContext;
@@ -28,11 +29,21 @@ class ThreadSafeContext;
 
 namespace clang {
 class IncrementalExecutor;
+class IncrementalCompilerBuilder;
 class TargetInfo;
 
 /// Common configuration and interface for incremental executor builders.
 class IncrementalExecutorBuilder {
 public:
+  /// Options passed to the backend when configuring execution.
+  struct Options {
+    bool IsOutOfProcess = false;
+    std::string ExecutorPath;
+    std::string RuntimePath;
+    unsigned SlabAllocateSize = 0;
+    bool UseSharedMemory = false;
+  };
+
   /// An optional external IncrementalExecutor.
   std::unique_ptr<IncrementalExecutor> IE;
   /// Frontend -mllvm arguments for backends that need to restore LLVM options.
@@ -44,6 +55,16 @@ class IncrementalExecutorBuilder {
   /// The selected backend provides this definition.
   static std::unique_ptr<IncrementalExecutorBuilder> createDefault();
 
+  /// Apply execution options and configure the compiler for this backend.
+  virtual llvm::Error configure(IncrementalCompilerBuilder &CB,
+                                const Options &Opts) = 0;
+
+  /// Probe whether this backend can JIT code for the host.
+  virtual bool supportsJIT() const = 0;
+
+  /// Return the host triple used by this backend.
+  virtual llvm::Expected<llvm::Triple> getHostJITTriple() const = 0;
+
   /// Return the supplied executor, or create one using the selected backend.
   llvm::Expected<std::unique_ptr<IncrementalExecutor>>
   create(llvm::orc::ThreadSafeContext &TSC, const clang::TargetInfo &TI);
diff --git a/clang/include/clang/Interpreter/OrcIncrementalExecutorBuilder.h 
b/clang/include/clang/Interpreter/OrcIncrementalExecutorBuilder.h
index d443f69f65710..98de99bb99f4e 100644
--- a/clang/include/clang/Interpreter/OrcIncrementalExecutorBuilder.h
+++ b/clang/include/clang/Interpreter/OrcIncrementalExecutorBuilder.h
@@ -61,6 +61,11 @@ class OrcIncrementalExecutorBuilder : public 
IncrementalExecutorBuilder {
   OrcIncrementalExecutorBuilder();
   ~OrcIncrementalExecutorBuilder() override;
 
+  llvm::Error configure(IncrementalCompilerBuilder &CB,
+                        const Options &Opts) override;
+  bool supportsJIT() const override;
+  llvm::Expected<llvm::Triple> getHostJITTriple() const override;
+
 private:
   llvm::Expected<std::unique_ptr<IncrementalExecutor>>
   createExecutor(llvm::orc::ThreadSafeContext &TSC,
diff --git a/clang/lib/Interpreter/OrcIncrementalExecutorBuilder.cpp 
b/clang/lib/Interpreter/OrcIncrementalExecutorBuilder.cpp
index 59e375a85fab7..89db2d71197a0 100644
--- a/clang/lib/Interpreter/OrcIncrementalExecutorBuilder.cpp
+++ b/clang/lib/Interpreter/OrcIncrementalExecutorBuilder.cpp
@@ -18,6 +18,7 @@
 #include "clang/Driver/Compilation.h"
 #include "clang/Driver/Driver.h"
 #include "clang/Driver/ToolChain.h"
+#include "clang/Interpreter/Interpreter.h"
 
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/SmallVector.h"
@@ -89,6 +90,36 @@ IncrementalExecutorBuilder::createDefault() {
   return std::make_unique<OrcIncrementalExecutorBuilder>();
 }
 
+llvm::Error
+OrcIncrementalExecutorBuilder::configure(IncrementalCompilerBuilder &CB,
+                                         const Options &Opts) {
+  IsOutOfProcess = Opts.IsOutOfProcess;
+  OOPExecutor = Opts.ExecutorPath;
+  OrcRuntimePath = Opts.RuntimePath;
+  if (OrcRuntimePath.empty())
+    CB.SetDriverCompilationCallback(UpdateOrcRuntimePathCB);
+  SlabAllocateSize = Opts.SlabAllocateSize;
+  UseSharedMemory = Opts.UseSharedMemory;
+  return llvm::Error::success();
+}
+
+bool OrcIncrementalExecutorBuilder::supportsJIT() const {
+  auto Triple = getHostJITTriple();
+  if (!Triple) {
+    llvm::consumeError(Triple.takeError());
+    return false;
+  }
+  return true;
+}
+
+llvm::Expected<llvm::Triple>
+OrcIncrementalExecutorBuilder::getHostJITTriple() const {
+  auto J = llvm::orc::LLJITBuilder().create();
+  if (!J)
+    return J.takeError();
+  return (*J)->getTargetTriple();
+}
+
 static llvm::Expected<llvm::orc::JITTargetMachineBuilder>
 createJITTargetMachineBuilder(const llvm::Triple &TT) {
   if (TT.getTriple() == llvm::sys::getProcessTriple())
diff --git a/clang/lib/Interpreter/Wasm.cpp b/clang/lib/Interpreter/Wasm.cpp
index 9351ab642c707..95e3b2f1ad96c 100644
--- a/clang/lib/Interpreter/Wasm.cpp
+++ b/clang/lib/Interpreter/Wasm.cpp
@@ -15,6 +15,7 @@
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
+#include "llvm/TargetParser/Host.h"
 #include <llvm/IR/LegacyPassManager.h>
 #include <llvm/IR/Module.h>
 #include <llvm/MC/TargetRegistry.h>
@@ -67,6 +68,20 @@ IncrementalExecutorBuilder::createDefault() {
   return std::make_unique<WasmIncrementalExecutorBuilder>();
 }
 
+llvm::Error
+WasmIncrementalExecutorBuilder::configure(IncrementalCompilerBuilder &CB,
+                                          const Options &Opts) {
+  if (Opts.IsOutOfProcess)
+    return llvm::createStringError("Out-of-process execution is not supported "
+                                   "by the WebAssembly executor");
+  return llvm::Error::success();
+}
+
+llvm::Expected<llvm::Triple>
+WasmIncrementalExecutorBuilder::getHostJITTriple() const {
+  return llvm::Triple(llvm::sys::getProcessTriple());
+}
+
 llvm::Expected<std::unique_ptr<IncrementalExecutor>>
 WasmIncrementalExecutorBuilder::createExecutor(
     llvm::orc::ThreadSafeContext &TSC, const clang::TargetInfo &TI) {
diff --git a/clang/lib/Interpreter/Wasm.h b/clang/lib/Interpreter/Wasm.h
index 3adf82cdacb7c..4eb6c8d05f37d 100644
--- a/clang/lib/Interpreter/Wasm.h
+++ b/clang/lib/Interpreter/Wasm.h
@@ -25,6 +25,12 @@
 namespace clang {
 
 class WasmIncrementalExecutorBuilder : public IncrementalExecutorBuilder {
+public:
+  llvm::Error configure(IncrementalCompilerBuilder &CB,
+                        const Options &Opts) override;
+  bool supportsJIT() const override { return false; }
+  llvm::Expected<llvm::Triple> getHostJITTriple() const override;
+
 private:
   llvm::Expected<std::unique_ptr<IncrementalExecutor>>
   createExecutor(llvm::orc::ThreadSafeContext &TSC,
diff --git a/clang/tools/clang-repl/CMakeLists.txt 
b/clang/tools/clang-repl/CMakeLists.txt
index bd66fa5aeb3d4..f83a7e607899b 100644
--- a/clang/tools/clang-repl/CMakeLists.txt
+++ b/clang/tools/clang-repl/CMakeLists.txt
@@ -7,10 +7,6 @@ set( LLVM_LINK_COMPONENTS
   TargetParser
   )
 
-if(NOT EMSCRIPTEN)
-  list(APPEND LLVM_LINK_COMPONENTS OrcJIT OrcShared)
-endif()
-
 add_clang_tool(clang-repl
   ClangRepl.cpp
 
diff --git a/clang/tools/clang-repl/ClangRepl.cpp 
b/clang/tools/clang-repl/ClangRepl.cpp
index a5165109c65eb..b98230d430666 100644
--- a/clang/tools/clang-repl/ClangRepl.cpp
+++ b/clang/tools/clang-repl/ClangRepl.cpp
@@ -17,13 +17,11 @@
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Interpreter/CodeCompletion.h"
 #include "clang/Interpreter/Interpreter.h"
-#include "clang/Interpreter/OrcIncrementalExecutorBuilder.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Sema/Sema.h"
 
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringRef.h"
-#include "llvm/ExecutionEngine/Orc/LLJIT.h"
 #include "llvm/LineEditor/LineEditor.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/FileSystem.h"
@@ -40,8 +38,6 @@
 #include <string>
 #include <vector>
 
-#include "llvm/ExecutionEngine/Orc/Debugging/DebuggerSupport.h"
-
 // Disable LSan for this test.
 // FIXME: Re-enable once we can assume GCC 13.2 or higher.
 // https://llvm.org/github.com/llvm/llvm-project/issues/67586.
@@ -276,32 +272,15 @@ int main(int argc, const char **argv) {
   llvm::InitializeAllAsmPrinters();
   llvm::InitializeAllAsmParsers();
 
-#ifdef __EMSCRIPTEN__
-  if (OptHostSupportsJit) {
-    llvm::outs() << "false\n";
-    return 0;
-  } else if (OptHostJitTriple) {
-    llvm::outs() << llvm::Triple::normalize(llvm::sys::getProcessTriple())
-                 << '\n';
-    return 0;
-  }
-#else
+  auto IEB = clang::IncrementalExecutorBuilder::createDefault();
   if (OptHostSupportsJit) {
-    auto J = llvm::orc::LLJITBuilder().create();
-    if (J)
-      llvm::outs() << "true\n";
-    else {
-      llvm::consumeError(J.takeError());
-      llvm::outs() << "false\n";
-    }
+    llvm::outs() << (IEB->supportsJIT() ? "true\n" : "false\n");
     return 0;
   } else if (OptHostJitTriple) {
-    auto J = ExitOnErr(llvm::orc::LLJITBuilder().create());
-    auto T = J->getTargetTriple();
+    auto T = ExitOnErr(IEB->getHostJITTriple());
     llvm::outs() << T.normalize() << '\n';
     return 0;
   }
-#endif
 
   ExitOnErr(sanitizeOopArguments(argv[0]));
 
@@ -314,20 +293,14 @@ int main(int argc, const char **argv) {
     return EXIT_FAILURE;
   }
 
-#ifdef __EMSCRIPTEN__
-  auto IEB = clang::IncrementalExecutorBuilder::createDefault();
-#else
-  auto IEB = std::make_unique<clang::OrcIncrementalExecutorBuilder>();
-  IEB->IsOutOfProcess = !OOPExecutor.empty() || !OOPExecutorConnect.empty();
-  IEB->OOPExecutor = OOPExecutor;
-  if (!OrcRuntimePath.empty())
-    IEB->OrcRuntimePath = OrcRuntimePath;
-  else
-    CB.SetDriverCompilationCallback(IEB->UpdateOrcRuntimePathCB);
-
-  IEB->SlabAllocateSize = *SizeOrErr;
-  IEB->UseSharedMemory = UseSharedMemory;
-#endif
+  clang::IncrementalExecutorBuilder::Options ExecutorOpts;
+  ExecutorOpts.IsOutOfProcess =
+      !OOPExecutor.empty() || !OOPExecutorConnect.empty();
+  ExecutorOpts.ExecutorPath = OOPExecutor;
+  ExecutorOpts.RuntimePath = OrcRuntimePath;
+  ExecutorOpts.SlabAllocateSize = *SizeOrErr;
+  ExecutorOpts.UseSharedMemory = UseSharedMemory;
+  ExitOnErr(IEB->configure(CB, ExecutorOpts));
 
   std::unique_ptr<clang::CompilerInstance> DeviceCI;
   if (CudaEnabled) {

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to