https://github.com/anutosh491 updated https://github.com/llvm/llvm-project/pull/132670
>From 6545414a97b6458333f399c7252ae55c88a42d62 Mon Sep 17 00:00:00 2001 From: anutosh491 <andersonbhat...@gmail.com> Date: Mon, 24 Mar 2025 10:09:59 +0530 Subject: [PATCH 1/6] Handle frontend options for clang-repl before calling executeAction --- clang/lib/Interpreter/Interpreter.cpp | 38 ++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/clang/lib/Interpreter/Interpreter.cpp b/clang/lib/Interpreter/Interpreter.cpp index fa4c1439c9261..5f48117dbf3b8 100644 --- a/clang/lib/Interpreter/Interpreter.cpp +++ b/clang/lib/Interpreter/Interpreter.cpp @@ -141,6 +141,37 @@ CreateCI(const llvm::opt::ArgStringList &Argv) { return std::move(Clang); } +static llvm::Error HandleFrontendOptions(const CompilerInstance &CI) { + const auto &FrontendOpts = CI.getFrontendOpts(); + + if (FrontendOpts.ShowHelp) { + driver::getDriverOptTable().printHelp( + llvm::outs(), "clang -cc1 [options] file...", + "LLVM 'Clang' Compiler: http://clang.llvm.org", + /*ShowHidden=*/false, /*ShowAllAliases=*/false, + llvm::opt::Visibility(driver::options::CC1Option)); + return llvm::createStringError(llvm::errc::not_supported, "Help displayed"); + } + + if (FrontendOpts.ShowVersion) { + llvm::cl::PrintVersionMessage(); + return llvm::createStringError(llvm::errc::not_supported, "Version displayed"); + } + + if (!FrontendOpts.LLVMArgs.empty()) { + unsigned NumArgs = FrontendOpts.LLVMArgs.size(); + auto Args = std::make_unique<const char*[]>(NumArgs + 2); + Args[0] = "clang-repl (LLVM option parsing)"; + for (unsigned i = 0; i != NumArgs; ++i) + Args[i + 1] = FrontendOpts.LLVMArgs[i].c_str(); + Args[NumArgs + 1] = nullptr; + llvm::errs() << "Parsing LLVM backend options via cl::ParseCommandLineOptions...\n"; + llvm::cl::ParseCommandLineOptions(NumArgs + 1, Args.get()); + } + + return llvm::Error::success(); +} + } // anonymous namespace namespace clang { @@ -451,7 +482,12 @@ const char *const Runtimes = R"( llvm::Expected<std::unique_ptr<Interpreter>> Interpreter::create(std::unique_ptr<CompilerInstance> CI) { - llvm::Error Err = llvm::Error::success(); + + llvm::Error Err = HandleFrontendOptions(*CI); + if (Err) { + return std::move(Err); + } + auto Interp = std::unique_ptr<Interpreter>(new Interpreter(std::move(CI), Err)); if (Err) >From fa4e295389e51da41b6b96baed099e739664b730 Mon Sep 17 00:00:00 2001 From: anutosh491 <andersonbhat...@gmail.com> Date: Mon, 24 Mar 2025 10:29:03 +0530 Subject: [PATCH 2/6] apply code formatting changes --- clang/lib/Interpreter/Interpreter.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/clang/lib/Interpreter/Interpreter.cpp b/clang/lib/Interpreter/Interpreter.cpp index 5f48117dbf3b8..3fbfd3c746bc7 100644 --- a/clang/lib/Interpreter/Interpreter.cpp +++ b/clang/lib/Interpreter/Interpreter.cpp @@ -155,17 +155,19 @@ static llvm::Error HandleFrontendOptions(const CompilerInstance &CI) { if (FrontendOpts.ShowVersion) { llvm::cl::PrintVersionMessage(); - return llvm::createStringError(llvm::errc::not_supported, "Version displayed"); + return llvm::createStringError(llvm::errc::not_supported, + "Version displayed"); } if (!FrontendOpts.LLVMArgs.empty()) { unsigned NumArgs = FrontendOpts.LLVMArgs.size(); - auto Args = std::make_unique<const char*[]>(NumArgs + 2); + auto Args = std::make_unique<const char *[]>(NumArgs + 2); Args[0] = "clang-repl (LLVM option parsing)"; for (unsigned i = 0; i != NumArgs; ++i) Args[i + 1] = FrontendOpts.LLVMArgs[i].c_str(); Args[NumArgs + 1] = nullptr; - llvm::errs() << "Parsing LLVM backend options via cl::ParseCommandLineOptions...\n"; + llvm::errs() + << "Parsing LLVM backend options via cl::ParseCommandLineOptions...\n"; llvm::cl::ParseCommandLineOptions(NumArgs + 1, Args.get()); } >From 6219d14843e1324b8eaf09c12ff6d4ee88104e8d Mon Sep 17 00:00:00 2001 From: anutosh491 <andersonbhat...@gmail.com> Date: Thu, 10 Apr 2025 16:09:01 +0530 Subject: [PATCH 3/6] Add tests for native cases --- clang/lib/Interpreter/Interpreter.cpp | 15 ++++++++++++--- clang/test/Interpreter/handlefrontendopts.cpp | 5 +++++ 2 files changed, 17 insertions(+), 3 deletions(-) create mode 100644 clang/test/Interpreter/handlefrontendopts.cpp diff --git a/clang/lib/Interpreter/Interpreter.cpp b/clang/lib/Interpreter/Interpreter.cpp index 3fbfd3c746bc7..15d3b033c1eee 100644 --- a/clang/lib/Interpreter/Interpreter.cpp +++ b/clang/lib/Interpreter/Interpreter.cpp @@ -163,11 +163,20 @@ static llvm::Error HandleFrontendOptions(const CompilerInstance &CI) { unsigned NumArgs = FrontendOpts.LLVMArgs.size(); auto Args = std::make_unique<const char *[]>(NumArgs + 2); Args[0] = "clang-repl (LLVM option parsing)"; - for (unsigned i = 0; i != NumArgs; ++i) + for (unsigned i = 0; i != NumArgs; ++i) { Args[i + 1] = FrontendOpts.LLVMArgs[i].c_str(); + // remove the leading '-' from the option name + if (Args[i + 1][0] == '-') { + auto *option = static_cast<llvm::cl::opt<bool> *>( + llvm::cl::getRegisteredOptions()[Args[i + 1] + 1]); + if (option) { + option->setInitialValue(true); + } else { + llvm::errs() << "Unknown LLVM option: " << Args[i + 1] << "\n"; + } + } + } Args[NumArgs + 1] = nullptr; - llvm::errs() - << "Parsing LLVM backend options via cl::ParseCommandLineOptions...\n"; llvm::cl::ParseCommandLineOptions(NumArgs + 1, Args.get()); } diff --git a/clang/test/Interpreter/handlefrontendopts.cpp b/clang/test/Interpreter/handlefrontendopts.cpp new file mode 100644 index 0000000000000..7596a6e745a03 --- /dev/null +++ b/clang/test/Interpreter/handlefrontendopts.cpp @@ -0,0 +1,5 @@ +// RUN: not clang-repl --Xcc -Xclang --Xcc -help 2>&1 | FileCheck %s --check-prefix=HELP +// RUN: not clang-repl --Xcc -Xclang --Xcc -version 2>&1 | FileCheck %s --check-prefix=VERSION + +// HELP: Help displayed +// VERSION: Version displayed \ No newline at end of file >From 17518c35665c6112cf4158f18abc70471ad76016 Mon Sep 17 00:00:00 2001 From: anutosh491 <andersonbhat...@gmail.com> Date: Tue, 16 Sep 2025 15:29:10 +0530 Subject: [PATCH 4/6] add tests --- clang/lib/Interpreter/Interpreter.cpp | 25 +++++++------------ clang/unittests/Interpreter/CMakeLists.txt | 1 + .../unittests/Interpreter/InterpreterTest.cpp | 20 +++++++++++++++ 3 files changed, 30 insertions(+), 16 deletions(-) diff --git a/clang/lib/Interpreter/Interpreter.cpp b/clang/lib/Interpreter/Interpreter.cpp index 26a3c1437ab8d..c7b63d64e453a 100644 --- a/clang/lib/Interpreter/Interpreter.cpp +++ b/clang/lib/Interpreter/Interpreter.cpp @@ -146,20 +146,14 @@ CreateCI(const llvm::opt::ArgStringList &Argv) { static llvm::Error HandleFrontendOptions(const CompilerInstance &CI) { const auto &FrontendOpts = CI.getFrontendOpts(); - if (FrontendOpts.ShowHelp) { - driver::getDriverOptTable().printHelp( - llvm::outs(), "clang -cc1 [options] file...", - "LLVM 'Clang' Compiler: http://clang.llvm.org", - /*ShowHidden=*/false, /*ShowAllAliases=*/false, - llvm::opt::Visibility(driver::options::CC1Option)); - return llvm::createStringError(llvm::errc::not_supported, "Help displayed"); - } - - if (FrontendOpts.ShowVersion) { - llvm::cl::PrintVersionMessage(); - return llvm::createStringError(llvm::errc::not_supported, - "Version displayed"); - } + // FIXME: Temporary duplication to honor -mllvm in clang-repl. + // clang/flang handle -mllvm in their tool-side ExecuteCompilerInvocation + // paths. clang-repl currently lacks that step, so we minimally parse + // FrontendOpts.LLVMArgs here to ensure -mllvm options take effect. + // Follow-up work: + // Move this -mllvm handling into a shared, driver/tool-level facility + // used by clang, clang-repl, flang, etc., and remove this library-side + // duplication. if (!FrontendOpts.LLVMArgs.empty()) { unsigned NumArgs = FrontendOpts.LLVMArgs.size(); @@ -167,7 +161,6 @@ static llvm::Error HandleFrontendOptions(const CompilerInstance &CI) { Args[0] = "clang-repl (LLVM option parsing)"; for (unsigned i = 0; i != NumArgs; ++i) { Args[i + 1] = FrontendOpts.LLVMArgs[i].c_str(); - // remove the leading '-' from the option name if (Args[i + 1][0] == '-') { auto *option = static_cast<llvm::cl::opt<bool> *>( llvm::cl::getRegisteredOptions()[Args[i + 1] + 1]); @@ -489,7 +482,7 @@ Interpreter::create(std::unique_ptr<CompilerInstance> CI, JITConfig Config) { Config.OrcRuntimePath = *OrcRuntimePathOrErr; } } - + llvm::Error Err = HandleFrontendOptions(*CI); if (Err) { return std::move(Err); diff --git a/clang/unittests/Interpreter/CMakeLists.txt b/clang/unittests/Interpreter/CMakeLists.txt index 7b8dcfc9b0546..0c04f7283b53c 100644 --- a/clang/unittests/Interpreter/CMakeLists.txt +++ b/clang/unittests/Interpreter/CMakeLists.txt @@ -80,6 +80,7 @@ target_link_options(ClangReplInterpreterTests PUBLIC "SHELL: -s ALLOW_MEMORY_GROWTH=1" PUBLIC "SHELL: -s STACK_SIZE=32mb" PUBLIC "SHELL: -s INITIAL_MEMORY=128mb" + PUBLIC "SHELL: -s NO_DISABLE_EXCEPTION_CATCHING" PUBLIC "SHELL: --emrun" PUBLIC "SHELL: -Wl,--export=__clang_Interpreter_SetValueWithAlloc" PUBLIC "SHELL: -Wl,--export=__clang_Interpreter_SetValueNoAlloc" diff --git a/clang/unittests/Interpreter/InterpreterTest.cpp b/clang/unittests/Interpreter/InterpreterTest.cpp index 9ff9092524d21..54e2e108ad4cb 100644 --- a/clang/unittests/Interpreter/InterpreterTest.cpp +++ b/clang/unittests/Interpreter/InterpreterTest.cpp @@ -443,4 +443,24 @@ TEST_F(InterpreterTest, TranslationUnit_CanonicalDecl) { sema.getASTContext().getTranslationUnitDecl()->getCanonicalDecl()); } + TEST_F(InterpreterTest, EmscriptenExceptionHandling) { +#ifndef __EMSCRIPTEN__ + GTEST_SKIP() << "This test only applies to Emscripten builds."; +#endif + + using Args = std::vector<const char *>; + Args ExtraArgs = { + "-std=c++20", + "-v", + "-fexceptions", + "-fcxx-exceptions", + "-mllvm", "-enable-emscripten-cxx-exceptions", + "-mllvm", "-enable-emscripten-sjlj"}; + + std::unique_ptr<Interpreter> Interp = createInterpreter(ExtraArgs); + + llvm::cantFail(Interp->ParseAndExecute( + "try { throw 1; } catch (...) { 0; }")); +} + } // end anonymous namespace >From f1810acc7eba72dda589dffb72196203c1410b5a Mon Sep 17 00:00:00 2001 From: anutosh491 <andersonbhat...@gmail.com> Date: Tue, 16 Sep 2025 15:31:23 +0530 Subject: [PATCH 5/6] delete unused test --- clang/test/Interpreter/handlefrontendopts.cpp | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 clang/test/Interpreter/handlefrontendopts.cpp diff --git a/clang/test/Interpreter/handlefrontendopts.cpp b/clang/test/Interpreter/handlefrontendopts.cpp deleted file mode 100644 index 7596a6e745a03..0000000000000 --- a/clang/test/Interpreter/handlefrontendopts.cpp +++ /dev/null @@ -1,5 +0,0 @@ -// RUN: not clang-repl --Xcc -Xclang --Xcc -help 2>&1 | FileCheck %s --check-prefix=HELP -// RUN: not clang-repl --Xcc -Xclang --Xcc -version 2>&1 | FileCheck %s --check-prefix=VERSION - -// HELP: Help displayed -// VERSION: Version displayed \ No newline at end of file >From 79de82c7b05498b783a2f8d6ca49217e9b51852b Mon Sep 17 00:00:00 2001 From: anutosh491 <andersonbhat...@gmail.com> Date: Tue, 16 Sep 2025 15:36:34 +0530 Subject: [PATCH 6/6] fix formatting --- .../unittests/Interpreter/InterpreterTest.cpp | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/clang/unittests/Interpreter/InterpreterTest.cpp b/clang/unittests/Interpreter/InterpreterTest.cpp index 54e2e108ad4cb..d1e10609067e4 100644 --- a/clang/unittests/Interpreter/InterpreterTest.cpp +++ b/clang/unittests/Interpreter/InterpreterTest.cpp @@ -443,24 +443,22 @@ TEST_F(InterpreterTest, TranslationUnit_CanonicalDecl) { sema.getASTContext().getTranslationUnitDecl()->getCanonicalDecl()); } - TEST_F(InterpreterTest, EmscriptenExceptionHandling) { +TEST_F(InterpreterTest, EmscriptenExceptionHandling) { #ifndef __EMSCRIPTEN__ GTEST_SKIP() << "This test only applies to Emscripten builds."; #endif using Args = std::vector<const char *>; - Args ExtraArgs = { - "-std=c++20", - "-v", - "-fexceptions", - "-fcxx-exceptions", - "-mllvm", "-enable-emscripten-cxx-exceptions", - "-mllvm", "-enable-emscripten-sjlj"}; + Args ExtraArgs = {"-std=c++20", "-v", + "-fexceptions", "-fcxx-exceptions", + "-mllvm", "-enable-emscripten-cxx-exceptions", + "-mllvm", "-enable-emscripten-sjlj"}; + std::unique_ptr<Interpreter> Interp = createInterpreter(ExtraArgs); - llvm::cantFail(Interp->ParseAndExecute( - "try { throw 1; } catch (...) { 0; }")); + llvm::cantFail( + Interp->ParseAndExecute("try { throw 1; } catch (...) { 0; }")); } } // end anonymous namespace _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits