[clang] [clang-repl] Handle frontend options for clang-repl before calling executeAction (PR #132670)
Anutosh Bhat via cfe-commits
cfe-commits at lists.llvm.org
Tue Sep 16 02:59:30 PDT 2025
https://github.com/anutosh491 updated https://github.com/llvm/llvm-project/pull/132670
>From 6545414a97b6458333f399c7252ae55c88a42d62 Mon Sep 17 00:00:00 2001
From: anutosh491 <andersonbhat491 at gmail.com>
Date: Mon, 24 Mar 2025 10:09:59 +0530
Subject: [PATCH 1/4] 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 <andersonbhat491 at gmail.com>
Date: Mon, 24 Mar 2025 10:29:03 +0530
Subject: [PATCH 2/4] 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 <andersonbhat491 at gmail.com>
Date: Thu, 10 Apr 2025 16:09:01 +0530
Subject: [PATCH 3/4] 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 <andersonbhat491 at gmail.com>
Date: Tue, 16 Sep 2025 15:29:10 +0530
Subject: [PATCH 4/4] 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
More information about the cfe-commits
mailing list