Author: Aaron Danen Date: 2025-08-05T14:50:48+01:00 New Revision: 2444c4a69861c643c6628b736affe5861cc79080
URL: https://github.com/llvm/llvm-project/commit/2444c4a69861c643c6628b736affe5861cc79080 DIFF: https://github.com/llvm/llvm-project/commit/2444c4a69861c643c6628b736affe5861cc79080.diff LOG: [clang-repl] add %help, documentation, and tests for %commands (#150348) 1. Added %commands to documentation 2. Added %help command to clang repl 3. Expanded parsing to throw unique errors in the case of users entering an invalid %command or using %lib without an argument 4. Added tests to check the behvaior of %help, %lib, and bad %commands Added: clang/test/Interpreter/bad_percent_command.cpp clang/test/Interpreter/dynamic-library-bad-args.cpp clang/test/Interpreter/help.cpp Modified: clang/docs/ClangRepl.rst clang/tools/clang-repl/ClangRepl.cpp Removed: ################################################################################ diff --git a/clang/docs/ClangRepl.rst b/clang/docs/ClangRepl.rst index 5399036c123fb..e7e86304f2561 100644 --- a/clang/docs/ClangRepl.rst +++ b/clang/docs/ClangRepl.rst @@ -159,8 +159,29 @@ Lamdas: clang-repl> welcome(); Welcome to REPL -Using Dynamic Library: -====================== +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: + +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,21 +210,30 @@ Using Dynamic Library: clang++-17 -c -o print.o print.cpp clang-17 -shared print.o -o print.so -Comments: -========= +Undo: +----- +The ``%undo`` command undoes 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. - -Closure or Termination: -======================= +Quit: +----- +The ``%quit`` command terminates clang-repl. .. code-block:: text - clang-repl>%quit + clang-repl> %quit + Just like Clang, Clang-Repl can be integrated in existing applications as a library 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..70f114f4644e3 --- /dev/null +++ b/clang/test/Interpreter/help.cpp @@ -0,0 +1,7 @@ +// RUN: cat %s | clang-repl | 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 diff --git a/clang/tools/clang-repl/ClangRepl.cpp b/clang/tools/clang-repl/ClangRepl.cpp index 54b27782d3db3..b666959c33b73 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> @@ -364,15 +365,34 @@ 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; } if (Input == R"(%undo)") { if (auto Err = Interp->Undo()) llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "error: "); + } else if (Input == R"(%help)") { + llvm::outs() << "%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", + 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] == '%') { + 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: "); } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits