Skip to content

Commit 2444c4a

Browse files
authored
[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
1 parent cc2a385 commit 2444c4a

File tree

5 files changed

+75
-10
lines changed

5 files changed

+75
-10
lines changed

clang/docs/ClangRepl.rst

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -159,8 +159,29 @@ Lamdas:
159159
clang-repl> welcome();
160160
Welcome to REPL
161161
162-
Using Dynamic Library:
163-
======================
162+
Comments:
163+
=========
164+
165+
.. code-block:: text
166+
167+
clang-repl> // Comments in Clang-Repl
168+
clang-repl> /* Comments in Clang-Repl */
169+
170+
Built in Commands:
171+
==================
172+
clang-repl has some special commands that are of the form ``%<something>``. To list all these commands, use the ``%help`` command:
173+
174+
Help:
175+
-----
176+
The ``%help`` command lists all built in clang-repl commands.
177+
178+
.. code-block:: text
179+
180+
clang-repl> %help
181+
182+
Using Dynamic Libraries:
183+
------------------------
184+
The ``%lib`` command links a dynamic library.
164185

165186
.. code-block:: text
166187
@@ -189,21 +210,30 @@ Using Dynamic Library:
189210
clang++-17 -c -o print.o print.cpp
190211
clang-17 -shared print.o -o print.so
191212
192-
Comments:
193-
=========
213+
Undo:
214+
-----
215+
The ``%undo`` command undoes the previous input.
194216

195217
.. code-block:: text
196218
197-
clang-repl> // Comments in Clang-Repl
198-
clang-repl> /* Comments in Clang-Repl */
219+
clang-repl> int a = 1; a
220+
(int) 1
221+
clang-repl> %undo
222+
clang-repl> a
223+
In file included from <<< inputs >>>:1:
224+
input_line_2:1:1: error: use of undeclared identifier 'a'
225+
1 | a
226+
* | ^
227+
error: Parsing failed.
199228
200-
201-
Closure or Termination:
202-
=======================
229+
Quit:
230+
-----
231+
The ``%quit`` command terminates clang-repl.
203232

204233
.. code-block:: text
205234
206-
clang-repl>%quit
235+
clang-repl> %quit
236+
207237
208238
209239
Just like Clang, Clang-Repl can be integrated in existing applications as a library
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// RUN: cat %s | clang-repl 2>&1 | FileCheck %s
2+
%foobar
3+
// CHECK: Invalid % command "%foobar", use "%help" to list commands
4+
%quit
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// RUN: cat %s | clang-repl 2>&1 | FileCheck %s
2+
%lib
3+
// CHECK: %lib expects 1 argument: the path to a dynamic library
4+
%quit

clang/test/Interpreter/help.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// RUN: cat %s | clang-repl | FileCheck %s
2+
%help
3+
// CHECK: %help list clang-repl %commands
4+
// CHECK-NEXT: %undo undo the previous input
5+
// CHECK-NEXT: %lib <path> link a dynamic library
6+
// CHECK-NEXT: %quit exit clang-repl
7+
%quit

clang/tools/clang-repl/ClangRepl.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "llvm/Support/ManagedStatic.h" // llvm_shutdown
2929
#include "llvm/Support/Signals.h"
3030
#include "llvm/Support/TargetSelect.h"
31+
#include "llvm/Support/raw_ostream.h"
3132
#include "llvm/TargetParser/Host.h"
3233
#include <optional>
3334

@@ -364,15 +365,34 @@ int main(int argc, const char **argv) {
364365
}
365366

366367
Input += L;
368+
// If we add more % commands, there should be better architecture than
369+
// this.
367370
if (Input == R"(%quit)") {
368371
break;
369372
}
370373
if (Input == R"(%undo)") {
371374
if (auto Err = Interp->Undo())
372375
llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "error: ");
376+
} else if (Input == R"(%help)") {
377+
llvm::outs() << "%help\t\tlist clang-repl %commands\n"
378+
<< "%undo\t\tundo the previous input\n"
379+
<< "%lib\t<path>\tlink a dynamic library\n"
380+
<< "%quit\t\texit clang-repl\n";
381+
} else if (Input == R"(%lib)") {
382+
auto Err = llvm::make_error<llvm::StringError>(
383+
"%lib expects 1 argument: the path to a dynamic library\n",
384+
std::error_code());
385+
llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "error: ");
373386
} else if (Input.rfind("%lib ", 0) == 0) {
374387
if (auto Err = Interp->LoadDynamicLibrary(Input.data() + 5))
375388
llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "error: ");
389+
} else if (Input[0] == '%') {
390+
auto Err = llvm::make_error<llvm::StringError>(
391+
llvm::formatv(
392+
"Invalid % command \"{0}\", use \"%help\" to list commands\n",
393+
Input),
394+
std::error_code());
395+
llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "error: ");
376396
} else if (auto Err = Interp->ParseAndExecute(Input)) {
377397
llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "error: ");
378398
}

0 commit comments

Comments
 (0)