[clang] [clang-repl] adding documentation and information for %commands (PR #150348)
Aaron Danen via cfe-commits
cfe-commits at lists.llvm.org
Fri Aug 1 13:09:59 PDT 2025
https://github.com/aadanen updated https://github.com/llvm/llvm-project/pull/150348
>From 4e24cb20efa22e364d41026ae40aec470ff786aa Mon Sep 17 00:00:00 2001
From: Aaron Danen <aaron.danen at gmail.com>
Date: Wed, 23 Jul 2025 18:01:14 -0700
Subject: [PATCH 01/17] added undo to docs in same format as %quit
---
clang/docs/ClangRepl.rst | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/clang/docs/ClangRepl.rst b/clang/docs/ClangRepl.rst
index 5399036c123fb..9ef82df28ee43 100644
--- a/clang/docs/ClangRepl.rst
+++ b/clang/docs/ClangRepl.rst
@@ -197,6 +197,13 @@ Comments:
clang-repl> // Comments in Clang-Repl
clang-repl> /* Comments in Clang-Repl */
+Undo:
+=====
+
+.. code-block:: text
+
+ clang-repl>%undo
+
Closure or Termination:
=======================
>From 752e4906b633b1343a52338027fdc0a6e36d6288 Mon Sep 17 00:00:00 2001
From: Aaron Danen <aaron.danen at gmail.com>
Date: Sat, 26 Jul 2025 10:01:30 -0700
Subject: [PATCH 02/17] implemented %help
---
clang/tools/clang-repl/ClangRepl.cpp | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/clang/tools/clang-repl/ClangRepl.cpp b/clang/tools/clang-repl/ClangRepl.cpp
index 54b27782d3db3..c347b45306031 100644
--- a/clang/tools/clang-repl/ClangRepl.cpp
+++ b/clang/tools/clang-repl/ClangRepl.cpp
@@ -185,7 +185,7 @@ struct ReplListCompleter {
clang::Interpreter &MainInterp;
ReplListCompleter(clang::IncrementalCompilerBuilder &CB,
clang::Interpreter &Interp)
- : CB(CB), MainInterp(Interp){};
+ : CB(CB), MainInterp(Interp) {};
std::vector<llvm::LineEditor::Completion> operator()(llvm::StringRef Buffer,
size_t Pos) const;
@@ -370,6 +370,8 @@ int main(int argc, const char **argv) {
if (Input == R"(%undo)") {
if (auto Err = Interp->Undo())
llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "error: ");
+ } else if (Input == R"(%help)") {
+ printf("clang-repl commands: { %%undo, %%quit }\n");
} else if (Input.rfind("%lib ", 0) == 0) {
if (auto Err = Interp->LoadDynamicLibrary(Input.data() + 5))
llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "error: ");
>From 99e2421447d730e40513ed799ece85c73b6987ce Mon Sep 17 00:00:00 2001
From: Aaron Danen <aaron.danen at gmail.com>
Date: Sat, 26 Jul 2025 10:53:39 -0700
Subject: [PATCH 03/17] blurb about %help on startup. better %help format
---
clang/tools/clang-repl/ClangRepl.cpp | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/clang/tools/clang-repl/ClangRepl.cpp b/clang/tools/clang-repl/ClangRepl.cpp
index c347b45306031..540253e377d98 100644
--- a/clang/tools/clang-repl/ClangRepl.cpp
+++ b/clang/tools/clang-repl/ClangRepl.cpp
@@ -347,7 +347,11 @@ int main(int argc, const char **argv) {
}
}
+ const char *percent_commands = "%help\tlist clang-repl %commands\n"
+ "%undo\tundo the previous input\n"
+ "%quit\texit clang-repl\n";
if (OptInputs.empty()) {
+ printf("%%help for list of clang-repl commands\n");
llvm::LineEditor LE("clang-repl");
std::string Input;
LE.setListCompleter(ReplListCompleter(CB, *Interp));
@@ -371,7 +375,7 @@ int main(int argc, const char **argv) {
if (auto Err = Interp->Undo())
llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "error: ");
} else if (Input == R"(%help)") {
- printf("clang-repl commands: { %%undo, %%quit }\n");
+ printf("%s\n", percent_commands);
} else if (Input.rfind("%lib ", 0) == 0) {
if (auto Err = Interp->LoadDynamicLibrary(Input.data() + 5))
llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "error: ");
>From f1f6d9c4a951d02d65abf306b069d3102f91481e Mon Sep 17 00:00:00 2001
From: Aaron Danen <aaron.danen at gmail.com>
Date: Sat, 26 Jul 2025 10:57:41 -0700
Subject: [PATCH 04/17] small change to opener message
---
clang/tools/clang-repl/ClangRepl.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/tools/clang-repl/ClangRepl.cpp b/clang/tools/clang-repl/ClangRepl.cpp
index 540253e377d98..c4718b208b586 100644
--- a/clang/tools/clang-repl/ClangRepl.cpp
+++ b/clang/tools/clang-repl/ClangRepl.cpp
@@ -351,7 +351,7 @@ int main(int argc, const char **argv) {
"%undo\tundo the previous input\n"
"%quit\texit clang-repl\n";
if (OptInputs.empty()) {
- printf("%%help for list of clang-repl commands\n");
+ printf("type %%help to list clang-repl commands\n");
llvm::LineEditor LE("clang-repl");
std::string Input;
LE.setListCompleter(ReplListCompleter(CB, *Interp));
>From 1cd23df9a039595dbced49dd222065b0d5f7e6e2 Mon Sep 17 00:00:00 2001
From: Aaron Danen <aaron.danen at gmail.com>
Date: Mon, 28 Jul 2025 10:39:46 -0700
Subject: [PATCH 05/17] added %help to docs
---
clang/docs/ClangRepl.rst | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/clang/docs/ClangRepl.rst b/clang/docs/ClangRepl.rst
index 9ef82df28ee43..e2b33a01b15ed 100644
--- a/clang/docs/ClangRepl.rst
+++ b/clang/docs/ClangRepl.rst
@@ -197,6 +197,13 @@ Comments:
clang-repl> // Comments in Clang-Repl
clang-repl> /* Comments in Clang-Repl */
+Help:
+=====
+
+.. code-block:: text
+
+ clang-repl>%help
+
Undo:
=====
>From cde1b98e47161b8645af29cceb2e057b2e937c66 Mon Sep 17 00:00:00 2001
From: Aaron Danen <aaron.danen at gmail.com>
Date: Mon, 28 Jul 2025 16:48:08 -0700
Subject: [PATCH 06/17] got rid of printf(), added bad % command handling
---
clang/tools/clang-repl/ClangRepl.cpp | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/clang/tools/clang-repl/ClangRepl.cpp b/clang/tools/clang-repl/ClangRepl.cpp
index c4718b208b586..e68aabcd43e0f 100644
--- a/clang/tools/clang-repl/ClangRepl.cpp
+++ b/clang/tools/clang-repl/ClangRepl.cpp
@@ -28,6 +28,7 @@
#include "llvm/Support/ManagedStatic.h" // llvm_shutdown
#include "llvm/Support/Signals.h"
#include "llvm/Support/TargetSelect.h"
+#include "llvm/Support/raw_ostream.h"
#include "llvm/TargetParser/Host.h"
#include <optional>
@@ -347,11 +348,15 @@ int main(int argc, const char **argv) {
}
}
- const char *percent_commands = "%help\tlist clang-repl %commands\n"
- "%undo\tundo the previous input\n"
- "%quit\texit clang-repl\n";
+ // if we add more % commands, there should be better architecture than this
+ const char *help_output = "%help\tlist clang-repl %commands\n"
+ "%undo\tundo the previous input\n"
+ "%quit\texit clang-repl\n";
+ const char *help_prompt = "type %help to list clang-repl commands\n";
+
+ llvm::raw_ostream &OS = llvm::outs();
if (OptInputs.empty()) {
- printf("type %%help to list clang-repl commands\n");
+ OS << help_prompt;
llvm::LineEditor LE("clang-repl");
std::string Input;
LE.setListCompleter(ReplListCompleter(CB, *Interp));
@@ -375,7 +380,9 @@ int main(int argc, const char **argv) {
if (auto Err = Interp->Undo())
llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "error: ");
} else if (Input == R"(%help)") {
- printf("%s\n", percent_commands);
+ OS << help_output << '\n';
+ } else if (Input[0] == '%') { // make sure this is evaluated last
+ OS << "Invalid % command: \"" << Input << "\". " << help_prompt;
} else if (Input.rfind("%lib ", 0) == 0) {
if (auto Err = Interp->LoadDynamicLibrary(Input.data() + 5))
llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "error: ");
>From d5b1c8a71cda459f2fb450aa0ea69d1328a07117 Mon Sep 17 00:00:00 2001
From: Aaron Danen <aaron.danen at gmail.com>
Date: Tue, 29 Jul 2025 10:17:17 -0700
Subject: [PATCH 07/17] Removed %help prompt. Fixed % command parsing.
---
clang/tools/clang-repl/ClangRepl.cpp | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/clang/tools/clang-repl/ClangRepl.cpp b/clang/tools/clang-repl/ClangRepl.cpp
index e68aabcd43e0f..5ebe4bc173fed 100644
--- a/clang/tools/clang-repl/ClangRepl.cpp
+++ b/clang/tools/clang-repl/ClangRepl.cpp
@@ -352,11 +352,9 @@ int main(int argc, const char **argv) {
const char *help_output = "%help\tlist clang-repl %commands\n"
"%undo\tundo the previous input\n"
"%quit\texit clang-repl\n";
- const char *help_prompt = "type %help to list clang-repl commands\n";
llvm::raw_ostream &OS = llvm::outs();
if (OptInputs.empty()) {
- OS << help_prompt;
llvm::LineEditor LE("clang-repl");
std::string Input;
LE.setListCompleter(ReplListCompleter(CB, *Interp));
@@ -381,11 +379,14 @@ int main(int argc, const char **argv) {
llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "error: ");
} else if (Input == R"(%help)") {
OS << help_output << '\n';
- } else if (Input[0] == '%') { // make sure this is evaluated last
- OS << "Invalid % command: \"" << Input << "\". " << help_prompt;
+ } else if (Input == R"(%lib)") {
+ OS << "%lib expects 1 argument: the path to a dynamic library\n";
} else if (Input.rfind("%lib ", 0) == 0) {
if (auto Err = Interp->LoadDynamicLibrary(Input.data() + 5))
llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "error: ");
+ } else if (Input[0] == '%') { // make sure this is evaluated last
+ OS << "Invalid % command \"" << Input << "\", "
+ << "use \"%help\" to list commands\n";
} else if (auto Err = Interp->ParseAndExecute(Input)) {
llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "error: ");
}
>From b7821e5917c5fe490df6730fc4ceb84314238e5d Mon Sep 17 00:00:00 2001
From: Aaron Danen <aaron.danen at gmail.com>
Date: Tue, 29 Jul 2025 10:23:35 -0700
Subject: [PATCH 08/17] added %lib to %help output
---
clang/tools/clang-repl/ClangRepl.cpp | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/clang/tools/clang-repl/ClangRepl.cpp b/clang/tools/clang-repl/ClangRepl.cpp
index 5ebe4bc173fed..c073ac946f31c 100644
--- a/clang/tools/clang-repl/ClangRepl.cpp
+++ b/clang/tools/clang-repl/ClangRepl.cpp
@@ -349,9 +349,10 @@ int main(int argc, const char **argv) {
}
// if we add more % commands, there should be better architecture than this
- const char *help_output = "%help\tlist clang-repl %commands\n"
- "%undo\tundo the previous input\n"
- "%quit\texit clang-repl\n";
+ const char *help_output = "%help\t\tlist clang-repl %commands\n"
+ "%undo\t\tundo the previous input\n"
+ "%lib\t<path>\tlink a dynamic library\n"
+ "%quit\t\texit clang-repl\n";
llvm::raw_ostream &OS = llvm::outs();
if (OptInputs.empty()) {
>From 05516ca52eecba1bf4e029bbe8cded55162ca138 Mon Sep 17 00:00:00 2001
From: Aaron Danen <aaron.danen at gmail.com>
Date: Tue, 29 Jul 2025 10:24:23 -0700
Subject: [PATCH 09/17] Reformatted comment grammer
---
clang/tools/clang-repl/ClangRepl.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/tools/clang-repl/ClangRepl.cpp b/clang/tools/clang-repl/ClangRepl.cpp
index c073ac946f31c..7ef4889c94c4b 100644
--- a/clang/tools/clang-repl/ClangRepl.cpp
+++ b/clang/tools/clang-repl/ClangRepl.cpp
@@ -348,7 +348,7 @@ int main(int argc, const char **argv) {
}
}
- // if we add more % commands, there should be better architecture than this
+ // If we add more % commands, there should be better architecture than this.
const char *help_output = "%help\t\tlist clang-repl %commands\n"
"%undo\t\tundo the previous input\n"
"%lib\t<path>\tlink a dynamic library\n"
>From ec701ca16035256c2a147b35ea41004877b3eaab Mon Sep 17 00:00:00 2001
From: Aaron Danen <aaron.danen at gmail.com>
Date: Tue, 29 Jul 2025 11:04:10 -0700
Subject: [PATCH 10/17] updated documentation
---
clang/docs/ClangRepl.rst | 54 ++++++++++++++++++++++++++--------------
1 file changed, 36 insertions(+), 18 deletions(-)
diff --git a/clang/docs/ClangRepl.rst b/clang/docs/ClangRepl.rst
index e2b33a01b15ed..012a61a3f079d 100644
--- a/clang/docs/ClangRepl.rst
+++ b/clang/docs/ClangRepl.rst
@@ -159,8 +159,21 @@ Lamdas:
clang-repl> welcome();
Welcome to REPL
-Using Dynamic Library:
-======================
+Built in Commands:
+==================
+clang-repl has some special commands that are of the form `%<something>`. To list all these commands, use the `%help` command:
+
+Help:
+=====
+The `%help` command lists all built in clang-repl commands.
+
+.. code-block:: text
+
+ clang-repl> %help
+
+Using Dynamic Libraries:
+========================
+The `%lib` command links a dynamic library.
.. code-block:: text
@@ -189,35 +202,40 @@ Using Dynamic Library:
clang++-17 -c -o print.o print.cpp
clang-17 -shared print.o -o print.so
-Comments:
-=========
+Undo:
+=====
+The `%undo` command reverts the previous input.
.. code-block:: text
- clang-repl> // Comments in Clang-Repl
- clang-repl> /* Comments in Clang-Repl */
+ clang-repl> int a = 1; a
+ (int) 1
+ clang-repl> %undo
+ clang-repl> a
+ In file included from <<< inputs >>>:1:
+ input_line_2:1:1: error: use of undeclared identifier 'a'
+ 1 | a
+ * | ^
+ error: Parsing failed.
-Help:
-=====
+
+Quit:
+=======================
+The `%quit` command terminates clang-repl.
.. code-block:: text
- clang-repl>%help
+ clang-repl> %quit
-Undo:
-=====
+Comments:
+=========
.. code-block:: text
- clang-repl>%undo
-
-
-Closure or Termination:
-=======================
+ clang-repl> // Comments in Clang-Repl
+ clang-repl> /* Comments in Clang-Repl */
-.. code-block:: text
- clang-repl>%quit
Just like Clang, Clang-Repl can be integrated in existing applications as a library
>From 94f3128984c7111d33dc61a837542829fdcd530c Mon Sep 17 00:00:00 2001
From: Aaron Danen <aaron.danen at gmail.com>
Date: Tue, 29 Jul 2025 12:21:53 -0700
Subject: [PATCH 11/17] switched from raw_ostream to logging errors
---
clang/tools/clang-repl/ClangRepl.cpp | 20 ++++++++++++++------
1 file changed, 14 insertions(+), 6 deletions(-)
diff --git a/clang/tools/clang-repl/ClangRepl.cpp b/clang/tools/clang-repl/ClangRepl.cpp
index 7ef4889c94c4b..a5268aab16590 100644
--- a/clang/tools/clang-repl/ClangRepl.cpp
+++ b/clang/tools/clang-repl/ClangRepl.cpp
@@ -28,7 +28,6 @@
#include "llvm/Support/ManagedStatic.h" // llvm_shutdown
#include "llvm/Support/Signals.h"
#include "llvm/Support/TargetSelect.h"
-#include "llvm/Support/raw_ostream.h"
#include "llvm/TargetParser/Host.h"
#include <optional>
@@ -354,7 +353,8 @@ int main(int argc, const char **argv) {
"%lib\t<path>\tlink a dynamic library\n"
"%quit\t\texit clang-repl\n";
- llvm::raw_ostream &OS = llvm::outs();
+ const char *lib_bad_args =
+ "%lib expects 1 argument: the path to a dynamic library\n";
if (OptInputs.empty()) {
llvm::LineEditor LE("clang-repl");
std::string Input;
@@ -379,15 +379,23 @@ int main(int argc, const char **argv) {
if (auto Err = Interp->Undo())
llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "error: ");
} else if (Input == R"(%help)") {
- OS << help_output << '\n';
+ auto Err =
+ llvm::make_error<llvm::StringError>(help_output, std::error_code());
+ llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "");
} else if (Input == R"(%lib)") {
- OS << "%lib expects 1 argument: the path to a dynamic library\n";
+ auto Err = llvm::make_error<llvm::StringError>(lib_bad_args,
+ std::error_code());
+ llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "error: ");
} else if (Input.rfind("%lib ", 0) == 0) {
if (auto Err = Interp->LoadDynamicLibrary(Input.data() + 5))
llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "error: ");
} else if (Input[0] == '%') { // make sure this is evaluated last
- OS << "Invalid % command \"" << Input << "\", "
- << "use \"%help\" to list commands\n";
+ auto Err = llvm::make_error<llvm::StringError>(
+ llvm::formatv(
+ "Invalid % command \"{0}\", use \"%help\" to list commands\n",
+ Input),
+ std::error_code());
+ llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "error: ");
} else if (auto Err = Interp->ParseAndExecute(Input)) {
llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "error: ");
}
>From 54ea08cb33912780806db75b628c46dc7f7847e7 Mon Sep 17 00:00:00 2001
From: Aaron Danen <aaron.danen at gmail.com>
Date: Thu, 31 Jul 2025 08:33:24 -0700
Subject: [PATCH 12/17] reverted clang-format on one spot
---
clang/tools/clang-repl/ClangRepl.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/tools/clang-repl/ClangRepl.cpp b/clang/tools/clang-repl/ClangRepl.cpp
index a5268aab16590..a359f59452182 100644
--- a/clang/tools/clang-repl/ClangRepl.cpp
+++ b/clang/tools/clang-repl/ClangRepl.cpp
@@ -185,7 +185,7 @@ struct ReplListCompleter {
clang::Interpreter &MainInterp;
ReplListCompleter(clang::IncrementalCompilerBuilder &CB,
clang::Interpreter &Interp)
- : CB(CB), MainInterp(Interp) {};
+ : CB(CB), MainInterp(Interp){};
std::vector<llvm::LineEditor::Completion> operator()(llvm::StringRef Buffer,
size_t Pos) const;
>From fafd7bd669d29cb03cbfae9424974a81b14874c1 Mon Sep 17 00:00:00 2001
From: Aaron Danen <aaron.danen at gmail.com>
Date: Thu, 31 Jul 2025 09:50:33 -0700
Subject: [PATCH 13/17] fixed documentation
---
clang/docs/ClangRepl.rst | 37 +++++++++++++++++++------------------
1 file changed, 19 insertions(+), 18 deletions(-)
diff --git a/clang/docs/ClangRepl.rst b/clang/docs/ClangRepl.rst
index 012a61a3f079d..338e771829f91 100644
--- a/clang/docs/ClangRepl.rst
+++ b/clang/docs/ClangRepl.rst
@@ -159,21 +159,31 @@ Lamdas:
clang-repl> welcome();
Welcome to REPL
+Comments:
+=========
+
+.. code-block:: text
+
+ clang-repl> // Comments in Clang-Repl
+ clang-repl> /* Comments in Clang-Repl */
+
+
+
Built in Commands:
==================
-clang-repl has some special commands that are of the form `%<something>`. To list all these commands, use the `%help` command:
+clang-repl has some special commands that are of the form ``%<something>``. To list all these commands, use the ``%help`` command:
Help:
-=====
-The `%help` command lists all built in clang-repl commands.
+-----
+The ``%help`` command lists all built in clang-repl commands.
.. code-block:: text
clang-repl> %help
Using Dynamic Libraries:
-========================
-The `%lib` command links a dynamic library.
+------------------------
+The ``%lib`` command links a dynamic library.
.. code-block:: text
@@ -203,8 +213,8 @@ The `%lib` command links a dynamic library.
clang-17 -shared print.o -o print.so
Undo:
-=====
-The `%undo` command reverts the previous input.
+-----
+The ``%undo`` command undoes the previous input.
.. code-block:: text
@@ -220,22 +230,13 @@ The `%undo` command reverts the previous input.
Quit:
-=======================
-The `%quit` command terminates clang-repl.
+-----
+The ``%quit`` command terminates clang-repl.
.. code-block:: text
clang-repl> %quit
-Comments:
-=========
-
-.. code-block:: text
-
- clang-repl> // Comments in Clang-Repl
- clang-repl> /* Comments in Clang-Repl */
-
-
Just like Clang, Clang-Repl can be integrated in existing applications as a library
>From 4ceeef5a4dcd2b929607ce0b10f944ac1b6ea14e Mon Sep 17 00:00:00 2001
From: Aaron Danen <aaron.danen at gmail.com>
Date: Thu, 31 Jul 2025 09:53:39 -0700
Subject: [PATCH 14/17] moved string and deleted bad comment
---
clang/tools/clang-repl/ClangRepl.cpp | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/clang/tools/clang-repl/ClangRepl.cpp b/clang/tools/clang-repl/ClangRepl.cpp
index a359f59452182..51ee65f12991c 100644
--- a/clang/tools/clang-repl/ClangRepl.cpp
+++ b/clang/tools/clang-repl/ClangRepl.cpp
@@ -348,10 +348,6 @@ int main(int argc, const char **argv) {
}
// If we add more % commands, there should be better architecture than this.
- const char *help_output = "%help\t\tlist clang-repl %commands\n"
- "%undo\t\tundo the previous input\n"
- "%lib\t<path>\tlink a dynamic library\n"
- "%quit\t\texit clang-repl\n";
const char *lib_bad_args =
"%lib expects 1 argument: the path to a dynamic library\n";
@@ -379,8 +375,12 @@ int main(int argc, const char **argv) {
if (auto Err = Interp->Undo())
llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "error: ");
} else if (Input == R"(%help)") {
- auto Err =
- llvm::make_error<llvm::StringError>(help_output, std::error_code());
+ auto Err = llvm::make_error<llvm::StringError>(
+ "%help\t\tlist clang-repl %commands\n"
+ "%undo\t\tundo the previous input\n"
+ "%lib\t<path>\tlink a dynamic library\n"
+ "%quit\t\texit clang-repl\n",
+ std::error_code());
llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "");
} else if (Input == R"(%lib)") {
auto Err = llvm::make_error<llvm::StringError>(lib_bad_args,
@@ -389,7 +389,7 @@ int main(int argc, const char **argv) {
} else if (Input.rfind("%lib ", 0) == 0) {
if (auto Err = Interp->LoadDynamicLibrary(Input.data() + 5))
llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "error: ");
- } else if (Input[0] == '%') { // make sure this is evaluated last
+ } else if (Input[0] == '%') {
auto Err = llvm::make_error<llvm::StringError>(
llvm::formatv(
"Invalid % command \"{0}\", use \"%help\" to list commands\n",
>From a84ff32fac5d75f07090cc5fa65388e8ef31c0a4 Mon Sep 17 00:00:00 2001
From: Aaron Danen <aaron.danen at gmail.com>
Date: Thu, 31 Jul 2025 11:44:06 -0700
Subject: [PATCH 15/17] should move this string as well
---
clang/tools/clang-repl/ClangRepl.cpp | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/clang/tools/clang-repl/ClangRepl.cpp b/clang/tools/clang-repl/ClangRepl.cpp
index 51ee65f12991c..cb031c379aa39 100644
--- a/clang/tools/clang-repl/ClangRepl.cpp
+++ b/clang/tools/clang-repl/ClangRepl.cpp
@@ -349,8 +349,6 @@ int main(int argc, const char **argv) {
// If we add more % commands, there should be better architecture than this.
- const char *lib_bad_args =
- "%lib expects 1 argument: the path to a dynamic library\n";
if (OptInputs.empty()) {
llvm::LineEditor LE("clang-repl");
std::string Input;
@@ -383,8 +381,9 @@ int main(int argc, const char **argv) {
std::error_code());
llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "");
} else if (Input == R"(%lib)") {
- auto Err = llvm::make_error<llvm::StringError>(lib_bad_args,
- std::error_code());
+ auto Err = llvm::make_error<llvm::StringError>(
+ "%lib expects 1 argument: the path to a dynamic library\n",
+ std::error_code());
llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "error: ");
} else if (Input.rfind("%lib ", 0) == 0) {
if (auto Err = Interp->LoadDynamicLibrary(Input.data() + 5))
>From 3b3d5f66e51cfcc3d6bd96d804f2a8562297b65a Mon Sep 17 00:00:00 2001
From: Aaron Danen <aaron.danen at gmail.com>
Date: Thu, 31 Jul 2025 11:45:20 -0700
Subject: [PATCH 16/17] added tests for %help, %lib, and invalid %commands
---
clang/test/Interpreter/bad_percent_command.cpp | 4 ++++
clang/test/Interpreter/dynamic-library-bad-args.cpp | 4 ++++
clang/test/Interpreter/help.cpp | 7 +++++++
3 files changed, 15 insertions(+)
create mode 100644 clang/test/Interpreter/bad_percent_command.cpp
create mode 100644 clang/test/Interpreter/dynamic-library-bad-args.cpp
create mode 100644 clang/test/Interpreter/help.cpp
diff --git a/clang/test/Interpreter/bad_percent_command.cpp b/clang/test/Interpreter/bad_percent_command.cpp
new file mode 100644
index 0000000000000..207570cac1873
--- /dev/null
+++ b/clang/test/Interpreter/bad_percent_command.cpp
@@ -0,0 +1,4 @@
+// RUN: cat %s | clang-repl 2>&1 | FileCheck %s
+%foobar
+// CHECK: Invalid % command "%foobar", use "%help" to list commands
+%quit
diff --git a/clang/test/Interpreter/dynamic-library-bad-args.cpp b/clang/test/Interpreter/dynamic-library-bad-args.cpp
new file mode 100644
index 0000000000000..f48a2657beacc
--- /dev/null
+++ b/clang/test/Interpreter/dynamic-library-bad-args.cpp
@@ -0,0 +1,4 @@
+// RUN: cat %s | clang-repl 2>&1 | FileCheck %s
+%lib
+// CHECK: %lib expects 1 argument: the path to a dynamic library
+%quit
diff --git a/clang/test/Interpreter/help.cpp b/clang/test/Interpreter/help.cpp
new file mode 100644
index 0000000000000..e18126a8e84be
--- /dev/null
+++ b/clang/test/Interpreter/help.cpp
@@ -0,0 +1,7 @@
+// RUN: cat %s | clang-repl 2>&1 | FileCheck %s
+%help
+// CHECK: %help list clang-repl %commands
+// CHECK-NEXT: %undo undo the previous input
+// CHECK-NEXT: %lib <path> link a dynamic library
+// CHECK-NEXT: %quit exit clang-repl
+%quit
>From 9593d1e727e9a75b76a65554bff2de36ab59902f Mon Sep 17 00:00:00 2001
From: Aaron Danen <aaron.danen at gmail.com>
Date: Fri, 1 Aug 2025 13:09:24 -0700
Subject: [PATCH 17/17] switched to raw_ostream
---
clang/test/Interpreter/help.cpp | 2 +-
clang/tools/clang-repl/ClangRepl.cpp | 17 ++++++++---------
2 files changed, 9 insertions(+), 10 deletions(-)
diff --git a/clang/test/Interpreter/help.cpp b/clang/test/Interpreter/help.cpp
index e18126a8e84be..70f114f4644e3 100644
--- a/clang/test/Interpreter/help.cpp
+++ b/clang/test/Interpreter/help.cpp
@@ -1,4 +1,4 @@
-// RUN: cat %s | clang-repl 2>&1 | FileCheck %s
+// RUN: cat %s | clang-repl | FileCheck %s
%help
// CHECK: %help list clang-repl %commands
// CHECK-NEXT: %undo undo the previous input
diff --git a/clang/tools/clang-repl/ClangRepl.cpp b/clang/tools/clang-repl/ClangRepl.cpp
index cb031c379aa39..62fbbbdfccdcf 100644
--- a/clang/tools/clang-repl/ClangRepl.cpp
+++ b/clang/tools/clang-repl/ClangRepl.cpp
@@ -28,6 +28,7 @@
#include "llvm/Support/ManagedStatic.h" // llvm_shutdown
#include "llvm/Support/Signals.h"
#include "llvm/Support/TargetSelect.h"
+#include "llvm/Support/raw_ostream.h"
#include "llvm/TargetParser/Host.h"
#include <optional>
@@ -347,11 +348,10 @@ int main(int argc, const char **argv) {
}
}
- // If we add more % commands, there should be better architecture than this.
-
if (OptInputs.empty()) {
llvm::LineEditor LE("clang-repl");
std::string Input;
+ llvm::raw_ostream &OS = llvm::outs();
LE.setListCompleter(ReplListCompleter(CB, *Interp));
while (std::optional<std::string> Line = LE.readLine()) {
llvm::StringRef L = *Line;
@@ -366,6 +366,8 @@ int main(int argc, const char **argv) {
}
Input += L;
+ // If we add more % commands, there should be better architecture than
+ // this.
if (Input == R"(%quit)") {
break;
}
@@ -373,13 +375,10 @@ int main(int argc, const char **argv) {
if (auto Err = Interp->Undo())
llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "error: ");
} else if (Input == R"(%help)") {
- auto Err = llvm::make_error<llvm::StringError>(
- "%help\t\tlist clang-repl %commands\n"
- "%undo\t\tundo the previous input\n"
- "%lib\t<path>\tlink a dynamic library\n"
- "%quit\t\texit clang-repl\n",
- std::error_code());
- llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "");
+ OS << "%help\t\tlist clang-repl %commands\n"
+ << "%undo\t\tundo the previous input\n"
+ << "%lib\t<path>\tlink a dynamic library\n"
+ << "%quit\t\texit clang-repl\n";
} else if (Input == R"(%lib)") {
auto Err = llvm::make_error<llvm::StringError>(
"%lib expects 1 argument: the path to a dynamic library\n",
More information about the cfe-commits
mailing list