https://github.com/anutosh491 created https://github.com/llvm/llvm-project/pull/166368
Fixes https://github.com/llvm/llvm-project/issues/166120 I could think of two approaches here 1) As per the comment https://github.com/llvm/llvm-project/issues/166120#issuecomment-3479552518 : Saying we could flush after each input line. Yes this would make sense and work too Here's an **unpolished diff** where 1) Flush after every input is parsed (through an IsFlushed var that is toggled for each input) 2) Once the flush is performed, we don't care about storing it in the list of PTUs or tracking it so we hit undo. ``` diff --git a/clang/include/clang/Interpreter/Interpreter.h b/clang/include/clang/Interpreter/Interpreter.h index 078d70b3b174..d07992a4ad02 100644 --- a/clang/include/clang/Interpreter/Interpreter.h +++ b/clang/include/clang/Interpreter/Interpreter.h @@ -234,6 +234,9 @@ private: // This function forces emission of the needed dtor. llvm::Expected<llvm::orc::ExecutorAddr> CompileDtorCall(CXXRecordDecl *CXXRD) const; + + bool IsOutOfProcess = false; + bool IsFlushing = false; }; } // namespace clang diff --git a/clang/lib/Interpreter/Interpreter.cpp b/clang/lib/Interpreter/Interpreter.cpp index a071d0312f76..9a178487dec7 100644 --- a/clang/lib/Interpreter/Interpreter.cpp +++ b/clang/lib/Interpreter/Interpreter.cpp @@ -347,6 +347,8 @@ const char *const Runtimes = R"( memcpy(Placement, Src, Size); } #endif // __cplusplus + #include <iostream> + #include <cstdio> EXTERN_C void *__clang_Interpreter_SetValueWithAlloc(void*, void*, void*); EXTERN_C void __clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, void *OpaqueType, ...); )"; @@ -648,6 +650,7 @@ llvm::Error Interpreter::CreateExecutor(JITConfig Config) { bool IsWindowsTarget = TargetTriple.isOSWindows(); if (!IsWindowsTarget && Config.IsOutOfProcess) { + IsOutOfProcess = true; if (!JITBuilder) { auto ResOrErr = outOfProcessJITBuilder(Config); if (!ResOrErr) @@ -732,6 +735,25 @@ llvm::Error Interpreter::ParseAndExecute(llvm::StringRef Code, Value *V) { } else *V = std::move(LastValue); } + + if (IsOutOfProcess && !IsFlushing) { + IsFlushing = true; // prevent recursion + + static const char FlushSnippet[] = R"( + std::cout.flush(); + std::cerr.flush(); + std::fflush(stdout); + std::fflush(stderr); + )"; + + if (auto FlushErr = ParseAndExecute(FlushSnippet)) + consumeError(std::move(FlushErr)); + + if (auto E = Undo()) + consumeError(std::move(E)); + IsFlushing = false; + } + return llvm::Error::success(); } ``` Downsides of this approach is we end up parsing and executing the above block for each input and then undoing the execution too everytime. Which just looks heavy ! >From 560ccf47c2cb4b56c4dbf805e89c323ba31af41a Mon Sep 17 00:00:00 2001 From: anutosh491 <[email protected]> Date: Tue, 4 Nov 2025 18:30:09 +0530 Subject: [PATCH] Fix inconsistent flushing between in-process and out-of-process --- clang/lib/Interpreter/Interpreter.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/clang/lib/Interpreter/Interpreter.cpp b/clang/lib/Interpreter/Interpreter.cpp index cde354c9cd8d1..f3927fc341341 100644 --- a/clang/lib/Interpreter/Interpreter.cpp +++ b/clang/lib/Interpreter/Interpreter.cpp @@ -351,6 +351,15 @@ const char *const Runtimes = R"( EXTERN_C void __clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, void *OpaqueType, ...); )"; +const char *const OOPRuntimes = R"( + #include <stdio.h> + __attribute__((constructor)) + static void __clang_repl_ioinit(void) { + setvbuf(stdout, NULL, _IONBF, 0); + setvbuf(stderr, NULL, _IONBF, 0); + } +)"; + llvm::Expected<std::pair<std::unique_ptr<llvm::orc::LLJITBuilder>, uint32_t>> Interpreter::outOfProcessJITBuilder(JITConfig Config) { std::unique_ptr<llvm::orc::ExecutorProcessControl> EPC; @@ -463,6 +472,11 @@ Interpreter::create(std::unique_ptr<CompilerInstance> CI, JITConfig Config) { if (auto E = Interp->ParseAndExecute(Runtimes)) return std::move(E); + if (Config.IsOutOfProcess) { + if (auto E = Interp->ParseAndExecute(OOPRuntimes)) + return std::move(E); + } + Interp->markUserCodeStart(); return std::move(Interp); _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
