@@ -202,10 +202,24 @@ inline void codeComplete(std::vector<std::string>& Results,
202202
203203#include " llvm/Support/Error.h"
204204
205+ #ifdef LLVM_BUILT_WITH_OOP_JIT
206+ #include " clang/Basic/Version.h"
207+ #include " llvm/TargetParser/Host.h"
208+
209+ #include " llvm/ExecutionEngine/Orc/Debugging/DebuggerSupport.h"
210+
211+ #include < unistd.h>
212+ #endif
213+
214+ #include < algorithm>
215+
216+ static const llvm::ExitOnError ExitOnError;
217+
205218namespace compat {
206219
207220inline std::unique_ptr<clang::Interpreter>
208- createClangInterpreter (std::vector<const char *>& args) {
221+ createClangInterpreter (std::vector<const char *>& args, int stdin_fd = 0 ,
222+ int stdout_fd = 1 , int stderr_fd = 2 ) {
209223 auto has_arg = [](const char * x, llvm::StringRef match = " cuda" ) {
210224 llvm::StringRef Arg = x;
211225 Arg = Arg.trim ().ltrim (' -' );
@@ -219,6 +233,15 @@ createClangInterpreter(std::vector<const char*>& args) {
219233 bool CudaEnabled = !gpu_args.empty ();
220234#endif
221235
236+ #if defined(_WIN32)
237+ bool outOfProcess = false ;
238+ #else
239+ bool outOfProcess =
240+ std::any_of (args.begin (), args.end (), [](const char * arg) {
241+ return llvm::StringRef (arg).trim () == " --use-oop-jit" ;
242+ });
243+ #endif
244+
222245 clang::IncrementalCompilerBuilder CB;
223246 CB.SetCompilerArgs ({args.begin (), it});
224247
@@ -243,11 +266,54 @@ createClangInterpreter(std::vector<const char*>& args) {
243266 (*ciOrErr)->LoadRequestedPlugins ();
244267 if (CudaEnabled)
245268 DeviceCI->LoadRequestedPlugins ();
269+
270+ #ifdef LLVM_BUILT_WITH_OOP_JIT
271+
272+ clang::Interpreter::JITConfig OutOfProcessConfig;
273+ if (outOfProcess) {
274+ OutOfProcessConfig.IsOutOfProcess = true ;
275+ OutOfProcessConfig.OOPExecutor =
276+ std::string (LLVM_SOURCE_DIR) + " /build/bin/llvm-jitlink-executor" ;
277+ OutOfProcessConfig.UseSharedMemory = false ;
278+ OutOfProcessConfig.SlabAllocateSize = 0 ;
279+ OutOfProcessConfig.CustomizeFork = [=] { // Lambda defined inline
280+ auto redirect = [](int from, int to) {
281+ if (from != to) {
282+ dup2 (from, to);
283+ close (from);
284+ }
285+ };
286+
287+ redirect (stdin_fd, STDIN_FILENO);
288+ redirect (stdout_fd, STDOUT_FILENO);
289+ redirect (stderr_fd, STDERR_FILENO);
290+
291+ setvbuf (stdout, nullptr , _IONBF, 0 );
292+ setvbuf (stderr, nullptr , _IONBF, 0 );
293+ };
294+ OutOfProcessConfig.OrcRuntimePath =
295+ std::string (LLVM_SOURCE_DIR) +
296+ " /build/lib/clang/20/lib/darwin/liborc_rt_osx.a" ;
297+ }
298+ auto innerOrErr =
299+ CudaEnabled
300+ ? clang::Interpreter::createWithCUDA (std::move (*ciOrErr),
301+ std::move (DeviceCI))
302+ : clang::Interpreter::create (std::move (*ciOrErr), OutOfProcessConfig);
303+ #else
304+ if (outOfProcess) {
305+ llvm::errs ()
306+ << " [CreateClangInterpreter]: No compatibility with out-of-process "
307+ " JIT. Running in-process JIT execution."
308+ << " (To enable recompile CppInterOp with patch applied and change "
309+ " VERSION file to 1.8.1;dev."
310+ << " \n " ;
311+ }
246312 auto innerOrErr =
247313 CudaEnabled ? clang::Interpreter::createWithCUDA (std::move (*ciOrErr),
248314 std::move (DeviceCI))
249315 : clang::Interpreter::create (std::move (*ciOrErr));
250-
316+ # endif
251317 if (!innerOrErr) {
252318 llvm::logAllUnhandledErrors (innerOrErr.takeError (), llvm::errs (),
253319 " Failed to build Interpreter:" );
0 commit comments