LLDB mainline
REPL.cpp
Go to the documentation of this file.
1//===-- REPL.cpp ----------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
10#include "lldb/Core/Debugger.h"
15#include "lldb/Host/HostInfo.h"
18#include "lldb/Target/Thread.h"
20
21#include <memory>
22
23using namespace lldb_private;
24
25char REPL::ID;
26
27REPL::REPL(Target &target) : m_target(target) {
28 // Make sure all option values have sane defaults
29 Debugger &debugger = m_target.GetDebugger();
30 debugger.SetShowProgress(false);
31 auto exe_ctx = debugger.GetCommandInterpreter().GetExecutionContext();
34}
35
36REPL::~REPL() = default;
37
38lldb::REPLSP REPL::Create(Status &err, lldb::LanguageType language,
39 Debugger *debugger, Target *target,
40 const char *repl_options) {
41 uint32_t idx = 0;
42 lldb::REPLSP ret;
43
44 while (REPLCreateInstance create_instance =
46 LanguageSet supported_languages =
48 if (!supported_languages[language])
49 continue;
50 ret = (*create_instance)(err, language, debugger, target, repl_options);
51 if (ret) {
52 break;
53 }
54 }
55
56 return ret;
57}
58
59std::string REPL::GetSourcePath() {
60 ConstString file_basename = GetSourceFileBasename();
61 FileSpec tmpdir_file_spec = HostInfo::GetProcessTempDir();
62 if (tmpdir_file_spec) {
63 tmpdir_file_spec.SetFilename(file_basename);
64 m_repl_source_path = tmpdir_file_spec.GetPath();
65 } else {
66 tmpdir_file_spec = FileSpec("/tmp");
67 tmpdir_file_spec.AppendPathComponent(file_basename.GetStringRef());
68 }
69
70 return tmpdir_file_spec.GetPath();
71}
72
73lldb::IOHandlerSP REPL::GetIOHandler() {
74 if (!m_io_handler_sp) {
75 Debugger &debugger = m_target.GetDebugger();
76 m_io_handler_sp = std::make_shared<IOHandlerEditline>(
77 debugger, IOHandler::Type::REPL,
78 "lldb-repl", // Name of input reader for history
79 llvm::StringRef("> "), // prompt
80 llvm::StringRef(". "), // Continuation prompt
81 true, // Multi-line
82 true, // The REPL prompt is always colored
83 1, // Line number
84 *this);
85
86 // Don't exit if CTRL+C is pressed
87 static_cast<IOHandlerEditline *>(m_io_handler_sp.get())
88 ->SetInterruptExits(false);
89
90 if (m_io_handler_sp->GetIsInteractive() &&
91 m_io_handler_sp->GetIsRealTerminal()) {
92 m_indent_str.assign(debugger.GetTabSize(), ' ');
94 } else {
95 m_indent_str.clear();
97 }
98 }
99 return m_io_handler_sp;
100}
101
102void REPL::IOHandlerActivated(IOHandler &io_handler, bool interactive) {
103 lldb::ProcessSP process_sp = m_target.GetProcessSP();
104 if (process_sp && process_sp->IsAlive())
105 return;
106 lldb::StreamFileSP error_sp(io_handler.GetErrorStreamFileSP());
107 error_sp->Printf("REPL requires a running target process.\n");
108 io_handler.SetIsDone(true);
109}
110
111bool REPL::IOHandlerInterrupt(IOHandler &io_handler) { return false; }
112
113void REPL::IOHandlerInputInterrupted(IOHandler &io_handler, std::string &line) {
114}
115
117 return (m_enable_auto_indent ? GetAutoIndentCharacters() : nullptr);
118}
119
121 if (ch == 'd')
122 return ConstString(":quit\n");
123 return ConstString();
124}
125
126const char *REPL::IOHandlerGetCommandPrefix() { return ":"; }
127
129 return "\nThe REPL (Read-Eval-Print-Loop) acts like an interpreter. "
130 "Valid statements, expressions, and declarations are immediately "
131 "compiled and executed.\n\n"
132 "The complete set of LLDB debugging commands are also available as "
133 "described below.\n\nCommands "
134 "must be prefixed with a colon at the REPL prompt (:quit for "
135 "example.) Typing just a colon "
136 "followed by return will switch to the LLDB prompt.\n\n"
137 "Type “< path” to read in code from a text file “path”.\n\n";
138}
139
141 // Check for meta command
142 const size_t num_lines = lines.GetSize();
143 if (num_lines == 1) {
144 const char *first_line = lines.GetStringAtIndex(0);
145 if (first_line[0] == ':')
146 return true; // Meta command is a single line where that starts with ':'
147 }
148
149 // Check if REPL input is done
150 std::string source_string(lines.CopyList());
151 return SourceIsComplete(source_string);
152}
153
155 std::string last_line = lines[lines.GetSize() - 1];
156
157 int actual_indent = 0;
158 for (char &ch : last_line) {
159 if (ch != ' ')
160 break;
161 ++actual_indent;
162 }
163
164 return actual_indent;
165}
166
168 const StringList &lines,
169 int cursor_position) {
171 return 0;
172
173 if (!lines.GetSize()) {
174 return 0;
175 }
176
177 int tab_size = io_handler.GetDebugger().GetTabSize();
178
179 lldb::offset_t desired_indent =
180 GetDesiredIndentation(lines, cursor_position, tab_size);
181
182 int actual_indent = REPL::CalculateActualIndentation(lines);
183
184 if (desired_indent == LLDB_INVALID_OFFSET)
185 return 0;
186
187 return (int)desired_indent - actual_indent;
188}
189
190static bool ReadCode(const std::string &path, std::string &code,
191 lldb::StreamFileSP &error_sp) {
192 auto &fs = FileSystem::Instance();
193 llvm::Twine pathTwine(path);
194 if (!fs.Exists(pathTwine)) {
195 error_sp->Printf("no such file at path '%s'\n", path.c_str());
196 return false;
197 }
198 if (!fs.Readable(pathTwine)) {
199 error_sp->Printf("could not read file at path '%s'\n", path.c_str());
200 return false;
201 }
202 const size_t file_size = fs.GetByteSize(pathTwine);
203 const size_t max_size = code.max_size();
204 if (file_size > max_size) {
205 error_sp->Printf("file at path '%s' too large: "
206 "file_size = %zu, max_size = %zu\n",
207 path.c_str(), file_size, max_size);
208 return false;
209 }
210 auto data_sp = fs.CreateDataBuffer(pathTwine);
211 if (data_sp == nullptr) {
212 error_sp->Printf("could not create buffer for file at path '%s'\n",
213 path.c_str());
214 return false;
215 }
216 code.assign((const char *)data_sp->GetBytes(), data_sp->GetByteSize());
217 return true;
218}
219
220void REPL::IOHandlerInputComplete(IOHandler &io_handler, std::string &code) {
221 lldb::StreamFileSP output_sp(io_handler.GetOutputStreamFileSP());
222 lldb::StreamFileSP error_sp(io_handler.GetErrorStreamFileSP());
223 bool extra_line = false;
224 bool did_quit = false;
225
226 if (code.empty()) {
228 static_cast<IOHandlerEditline &>(io_handler)
229 .SetBaseLineNumber(m_code.GetSize() + 1);
230 } else {
231 Debugger &debugger = m_target.GetDebugger();
233 extra_line = ci.GetSpaceReplPrompts();
234
236 ->GetThreadList()
237 .GetSelectedThread()
238 ->GetSelectedFrame(DoNoSelectMostRelevantFrame)
239 .get());
240
241 lldb::ProcessSP process_sp(exe_ctx.GetProcessSP());
242
243 if (code[0] == ':') {
244 // Meta command
245 // Strip the ':'
246 code.erase(0, 1);
247 if (!llvm::StringRef(code).trim().empty()) {
248 // "lldb" was followed by arguments, so just execute the command dump
249 // the results
250
251 // Turn off prompt on quit in case the user types ":quit"
252 const bool saved_prompt_on_quit = ci.GetPromptOnQuit();
253 if (saved_prompt_on_quit)
254 ci.SetPromptOnQuit(false);
255
256 // Execute the command
257 CommandReturnObject result(debugger.GetUseColor());
258 result.SetImmediateOutputStream(output_sp);
259 result.SetImmediateErrorStream(error_sp);
260 ci.HandleCommand(code.c_str(), eLazyBoolNo, result);
261
262 if (saved_prompt_on_quit)
263 ci.SetPromptOnQuit(true);
264
265 if (result.GetStatus() == lldb::eReturnStatusQuit) {
266 did_quit = true;
267 io_handler.SetIsDone(true);
268 if (debugger.CheckTopIOHandlerTypes(
270 // We typed "quit" or an alias to quit so we need to check if the
271 // command interpreter is above us and tell it that it is done as
272 // well so we don't drop back into the command interpreter if we
273 // have already quit
274 lldb::IOHandlerSP io_handler_sp(ci.GetIOHandler());
275 if (io_handler_sp)
276 io_handler_sp->SetIsDone(true);
277 }
278 }
279 } else {
280 // ":" was followed by no arguments, so push the LLDB command prompt
281 if (debugger.CheckTopIOHandlerTypes(
283 // If the user wants to get back to the command interpreter and the
284 // command interpreter is what launched the REPL, then just let the
285 // REPL exit and fall back to the command interpreter.
286 io_handler.SetIsDone(true);
287 } else {
288 // The REPL wasn't launched the by the command interpreter, it is the
289 // base IOHandler, so we need to get the command interpreter and
290 lldb::IOHandlerSP io_handler_sp(ci.GetIOHandler());
291 if (io_handler_sp) {
292 io_handler_sp->SetIsDone(false);
293 debugger.RunIOHandlerAsync(ci.GetIOHandler());
294 }
295 }
296 }
297 } else {
298 if (code[0] == '<') {
299 // User wants to read code from a file.
300 // Interpret rest of line as a literal path.
301 auto path = llvm::StringRef(code.substr(1)).trim().str();
302 if (!ReadCode(path, code, error_sp)) {
303 return;
304 }
305 }
306
307 // Unwind any expression we might have been running in case our REPL
308 // expression crashed and the user was looking around
310 Thread *thread = exe_ctx.GetThreadPtr();
311 if (thread && thread->UnwindInnermostExpression().Success()) {
312 thread->SetSelectedFrameByIndex(0, false);
313 exe_ctx.SetFrameSP(
315 }
316 }
317
318 const bool colorize_err = error_sp->GetFile().GetIsTerminalWithColors();
319
322 expr_options.SetKeepInMemory(true);
324 expr_options.SetGenerateDebugInfo(true);
325 expr_options.SetREPLEnabled(true);
326 expr_options.SetColorizeErrors(colorize_err);
327 expr_options.SetPoundLine(m_repl_source_path.c_str(),
328 m_code.GetSize() + 1);
329
330 expr_options.SetLanguage(GetLanguage());
331
332 PersistentExpressionState *persistent_state =
334 if (!persistent_state)
335 return;
336
337 const size_t var_count_before = persistent_state->GetSize();
338
339 const char *expr_prefix = nullptr;
340 lldb::ValueObjectSP result_valobj_sp;
342 lldb::ExpressionResults execution_results =
343 UserExpression::Evaluate(exe_ctx, expr_options, code.c_str(),
344 expr_prefix, result_valobj_sp, error,
345 nullptr); // fixed expression
346
347 if (llvm::Error err = OnExpressionEvaluated(exe_ctx, code, expr_options,
348 execution_results,
349 result_valobj_sp, error)) {
350 *error_sp << llvm::toString(std::move(err)) << "\n";
351 } else if (process_sp && process_sp->IsAlive()) {
352 bool add_to_code = true;
353 bool handled = false;
354 if (result_valobj_sp) {
356
357 if (result_valobj_sp->GetError().Success()) {
358 handled |= PrintOneVariable(debugger, output_sp, result_valobj_sp);
359 } else if (result_valobj_sp->GetError().GetError() ==
361 if (format != lldb::eFormatVoid && debugger.GetNotifyVoid()) {
362 error_sp->PutCString("(void)\n");
363 handled = true;
364 }
365 }
366 }
367
368 if (debugger.GetPrintDecls()) {
369 for (size_t vi = var_count_before, ve = persistent_state->GetSize();
370 vi != ve; ++vi) {
371 lldb::ExpressionVariableSP persistent_var_sp =
372 persistent_state->GetVariableAtIndex(vi);
373 lldb::ValueObjectSP valobj_sp = persistent_var_sp->GetValueObject();
374
375 PrintOneVariable(debugger, output_sp, valobj_sp,
376 persistent_var_sp.get());
377 }
378 }
379
380 if (!handled) {
381 bool useColors = error_sp->GetFile().GetIsTerminalWithColors();
382 switch (execution_results) {
385 add_to_code = false;
386 [[fallthrough]];
388 error_sp->Printf("%s\n", error.AsCString());
389 break;
390
392 break;
394 if (useColors) {
395 error_sp->Printf(ANSI_ESCAPE1(ANSI_FG_COLOR_RED));
396 error_sp->Printf(ANSI_ESCAPE1(ANSI_CTRL_BOLD));
397 }
398 error_sp->Printf("Execution interrupted. ");
399 if (useColors)
400 error_sp->Printf(ANSI_ESCAPE1(ANSI_CTRL_NORMAL));
401 error_sp->Printf("Enter code to recover and continue.\nEnter LLDB "
402 "commands to investigate (type :help for "
403 "assistance.)\n");
404 break;
405
407 // Breakpoint was hit, drop into LLDB command interpreter
408 if (useColors) {
409 error_sp->Printf(ANSI_ESCAPE1(ANSI_FG_COLOR_RED));
410 error_sp->Printf(ANSI_ESCAPE1(ANSI_CTRL_BOLD));
411 }
412 output_sp->Printf("Execution stopped at breakpoint. ");
413 if (useColors)
414 error_sp->Printf(ANSI_ESCAPE1(ANSI_CTRL_NORMAL));
415 output_sp->Printf("Enter LLDB commands to investigate (type help "
416 "for assistance.)\n");
417 {
418 lldb::IOHandlerSP io_handler_sp(ci.GetIOHandler());
419 if (io_handler_sp) {
420 io_handler_sp->SetIsDone(false);
421 debugger.RunIOHandlerAsync(ci.GetIOHandler());
422 }
423 }
424 break;
425
427 error_sp->Printf("error: timeout\n");
428 if (error.AsCString())
429 error_sp->Printf("error: %s\n", error.AsCString());
430 break;
432 // Shoulnd't happen???
433 error_sp->Printf("error: could not fetch result -- %s\n",
434 error.AsCString());
435 break;
437 // Shoulnd't happen???
438 error_sp->Printf("error: stopped for debug -- %s\n",
439 error.AsCString());
440 break;
442 // Shoulnd't happen???
443 error_sp->Printf("error: expression thread vanished -- %s\n",
444 error.AsCString());
445 break;
446 }
447 }
448
449 if (add_to_code) {
450 const uint32_t new_default_line = m_code.GetSize() + 1;
451
453
454 // Update our code on disk
455 if (!m_repl_source_path.empty()) {
456 auto file = FileSystem::Instance().Open(
460 lldb::eFilePermissionsFileDefault);
461 if (file) {
462 std::string code(m_code.CopyList());
463 code.append(1, '\n');
464 size_t bytes_written = code.size();
465 file.get()->Write(code.c_str(), bytes_written);
466 file.get()->Close();
467 } else {
468 std::string message = llvm::toString(file.takeError());
469 error_sp->Printf("error: couldn't open %s: %s\n",
470 m_repl_source_path.c_str(), message.c_str());
471 }
472
473 // Now set the default file and line to the REPL source file
475 FileSpec(m_repl_source_path), new_default_line);
476 }
477 static_cast<IOHandlerEditline &>(io_handler)
478 .SetBaseLineNumber(m_code.GetSize() + 1);
479 }
480 if (extra_line) {
481 output_sp->Printf("\n");
482 }
483 }
484 }
485
486 // Don't complain about the REPL process going away if we are in the
487 // process of quitting.
488 if (!did_quit && (!process_sp || !process_sp->IsAlive())) {
489 error_sp->Printf(
490 "error: REPL process is no longer alive, exiting REPL\n");
491 io_handler.SetIsDone(true);
492 }
493 }
494}
495
497 CompletionRequest &request) {
498 // Complete an LLDB command if the first character is a colon...
499 if (request.GetRawLine().startswith(":")) {
500 Debugger &debugger = m_target.GetDebugger();
501
502 // auto complete LLDB commands
503 llvm::StringRef new_line = request.GetRawLine().drop_front();
504 CompletionResult sub_result;
505 CompletionRequest sub_request(new_line, request.GetRawCursorPos() - 1,
506 sub_result);
507 debugger.GetCommandInterpreter().HandleCompletion(sub_request);
508 StringList matches, descriptions;
509 sub_result.GetMatches(matches);
510 // Prepend command prefix that was excluded in the completion request.
511 if (request.GetCursorIndex() == 0)
512 for (auto &match : matches)
513 match.insert(0, 1, ':');
514 sub_result.GetDescriptions(descriptions);
515 request.AddCompletions(matches, descriptions);
516 return;
517 }
518
519 // Strip spaces from the line and see if we had only spaces
520 if (request.GetRawLine().trim().empty()) {
521 // Only spaces on this line, so just indent
523 return;
524 }
525
526 std::string current_code;
527 current_code.append(m_code.CopyList());
528
529 IOHandlerEditline &editline = static_cast<IOHandlerEditline &>(io_handler);
530 const StringList *current_lines = editline.GetCurrentLines();
531 if (current_lines) {
532 const uint32_t current_line_idx = editline.GetCurrentLineIndex();
533
534 if (current_line_idx < current_lines->GetSize()) {
535 for (uint32_t i = 0; i < current_line_idx; ++i) {
536 const char *line_cstr = current_lines->GetStringAtIndex(i);
537 if (line_cstr) {
538 current_code.append("\n");
539 current_code.append(line_cstr);
540 }
541 }
542 }
543 }
544
545 current_code.append("\n");
546 current_code += request.GetRawLine();
547
548 CompleteCode(current_code, request);
549}
550
551bool QuitCommandOverrideCallback(void *baton, const char **argv) {
552 Target *target = (Target *)baton;
553 lldb::ProcessSP process_sp(target->GetProcessSP());
554 if (process_sp) {
555 process_sp->Destroy(false);
556 process_sp->GetTarget().GetDebugger().ClearIOHandlers();
557 }
558 return false;
559}
560
563
566
567 if (!error.Success())
568 return error;
569
570 Debugger &debugger = m_target.GetDebugger();
571
572 lldb::IOHandlerSP io_handler_sp(GetIOHandler());
573
574 FileSpec save_default_file;
575 uint32_t save_default_line = 0;
576
577 if (!m_repl_source_path.empty()) {
578 // Save the current default file and line
580 save_default_line);
581 }
582
583 debugger.RunIOHandlerAsync(io_handler_sp);
584
585 // Check if we are in dedicated REPL mode where LLDB was start with the "--
586 // repl" option from the command line. Currently we know this by checking if
587 // the debugger already has a IOHandler thread.
588 if (!debugger.HasIOHandlerThread()) {
589 // The debugger doesn't have an existing IOHandler thread, so this must be
590 // dedicated REPL mode...
592 debugger.StartIOHandlerThread();
593 llvm::StringRef command_name_str("quit");
594 CommandObject *cmd_obj =
596 command_name_str);
597 if (cmd_obj) {
598 assert(command_name_str.empty());
600 }
601 }
602
603 // Wait for the REPL command interpreter to get popped
604 io_handler_sp->WaitForPop();
605
607 // If we were in dedicated REPL mode we would have started the IOHandler
608 // thread, and we should kill our process
609 lldb::ProcessSP process_sp = m_target.GetProcessSP();
610 if (process_sp && process_sp->IsAlive())
611 process_sp->Destroy(false);
612
613 // Wait for the IO handler thread to exit (TODO: don't do this if the IO
614 // handler thread already exists...)
615 debugger.JoinIOHandlerThread();
616 }
617
618 // Restore the default file and line
619 if (save_default_file && save_default_line != 0)
621 save_default_line);
622 return error;
623}
#define ANSI_FG_COLOR_RED
Definition: AnsiTerminal.h:13
#define ANSI_ESCAPE1(s)
Definition: AnsiTerminal.h:68
#define ANSI_CTRL_NORMAL
Definition: AnsiTerminal.h:51
#define ANSI_CTRL_BOLD
Definition: AnsiTerminal.h:52
static llvm::raw_ostream & error(Stream &strm)
static bool ReadCode(const std::string &path, std::string &code, lldb::StreamFileSP &error_sp)
Definition: REPL.cpp:190
bool QuitCommandOverrideCallback(void *baton, const char **argv)
Definition: REPL.cpp:551
void HandleCompletion(CompletionRequest &request)
bool HandleCommand(const char *command_line, LazyBool add_to_history, const ExecutionContext &override_context, CommandReturnObject &result)
ExecutionContext GetExecutionContext() const
CommandObject * GetCommandObjectForCommand(llvm::StringRef &command_line)
lldb::IOHandlerSP GetIOHandler(bool force_create=false, CommandInterpreterRunOptions *options=nullptr)
void SetOverrideCallback(lldb::CommandOverrideCallback callback, void *baton)
void SetImmediateErrorStream(const lldb::StreamSP &stream_sp)
void SetImmediateOutputStream(const lldb::StreamSP &stream_sp)
lldb::ReturnStatus GetStatus() const
"lldb/Utility/ArgCompletionRequest.h"
void AddCompletion(llvm::StringRef completion, llvm::StringRef description="", CompletionMode mode=CompletionMode::Normal)
Adds a possible completion string.
void AddCompletions(const StringList &completions)
Adds multiple possible completion strings.
llvm::StringRef GetRawLine() const
Returns the raw user input used to create this CompletionRequest cut off at the cursor position.
void GetDescriptions(StringList &descriptions) const
Adds all collected completion descriptions to the given list.
void GetMatches(StringList &matches) const
Adds all collected completion matches to the given list.
A uniqued constant string class.
Definition: ConstString.h:39
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
Definition: ConstString.h:204
A class to manage flag bits.
Definition: Debugger.h:78
bool SetShowProgress(bool show_progress)
Definition: Debugger.cpp:401
bool GetPrintDecls() const
Definition: Debugger.cpp:530
CommandInterpreter & GetCommandInterpreter()
Definition: Debugger.h:171
bool HasIOHandlerThread() const
Definition: Debugger.cpp:2031
bool GetUseColor() const
Definition: Debugger.cpp:382
void RunIOHandlerAsync(const lldb::IOHandlerSP &reader_sp, bool cancel_top_handler=true)
Run the given IO handler and return immediately.
Definition: Debugger.cpp:1145
bool GetAutoIndent() const
Definition: Debugger.cpp:519
bool CheckTopIOHandlerTypes(IOHandler::Type top_type, IOHandler::Type second_top_type)
Definition: Debugger.cpp:1115
uint64_t GetTabSize() const
Definition: Debugger.cpp:541
bool GetNotifyVoid() const
Definition: Debugger.cpp:291
void SetLanguage(lldb::LanguageType language)
Definition: Target.h:311
void SetKeepInMemory(bool keep=true)
Definition: Target.h:340
void SetCoerceToId(bool coerce=true)
Definition: Target.h:326
void SetPoundLine(const char *path, uint32_t line) const
Definition: Target.h:406
void SetUseDynamic(lldb::DynamicValueType dynamic=lldb::eDynamicCanRunTarget)
Definition: Target.h:345
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
void SetFrameSP(const lldb::StackFrameSP &frame_sp)
Set accessor to set only the frame shared pointer.
const lldb::ProcessSP & GetProcessSP() const
Get accessor to get the process shared pointer.
Thread * GetThreadPtr() const
Returns a pointer to the thread object.
size_t GetSize()
Implementation of methods in ExpressionVariableListBase.
lldb::ExpressionVariableSP GetVariableAtIndex(size_t index)
A file utility class.
Definition: FileSpec.h:56
void AppendPathComponent(llvm::StringRef component)
Definition: FileSpec.cpp:446
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition: FileSpec.cpp:366
void SetFilename(ConstString filename)
Filename string set accessor.
Definition: FileSpec.cpp:344
int Open(const char *path, int flags, int mode)
Wraps ::open in a platform-independent way.
static FileSystem & Instance()
@ eOpenOptionWriteOnly
Definition: File.h:52
@ eOpenOptionCanCreate
Definition: File.h:56
@ eOpenOptionTruncate
Definition: File.h:57
const StringList * GetCurrentLines() const
Definition: IOHandler.h:408
uint32_t GetCurrentLineIndex() const
Definition: IOHandler.cpp:503
lldb::StreamFileSP GetErrorStreamFileSP()
Definition: IOHandler.cpp:107
Debugger & GetDebugger()
Definition: IOHandler.h:134
lldb::StreamFileSP GetOutputStreamFileSP()
Definition: IOHandler.cpp:105
void SetIsDone(bool b)
Definition: IOHandler.h:87
void OptionParsingStarting(ExecutionContext *execution_context) override
void OptionParsingStarting(ExecutionContext *execution_context) override
static REPLCreateInstance GetREPLCreateCallbackAtIndex(uint32_t idx)
static LanguageSet GetREPLSupportedLanguagesAtIndex(uint32_t idx)
const char * IOHandlerGetHelpPrologue() override
Definition: REPL.cpp:128
static int CalculateActualIndentation(const StringList &lines)
Definition: REPL.cpp:154
static char ID
LLVM RTTI support.
Definition: REPL.h:26
virtual Status DoInitialization()=0
virtual lldb::offset_t GetDesiredIndentation(const StringList &lines, int cursor_position, int tab_size)=0
const char * IOHandlerGetFixIndentationCharacters() override
Definition: REPL.cpp:116
int IOHandlerFixIndentation(IOHandler &io_handler, const StringList &lines, int cursor_position) override
Called when a new line is created or one of an identified set of indentation characters is typed.
Definition: REPL.cpp:167
virtual const char * GetAutoIndentCharacters()=0
OptionGroupValueObjectDisplay m_varobj_options
Definition: REPL.h:155
REPL(Target &target)
Definition: REPL.cpp:27
bool IOHandlerInterrupt(IOHandler &io_handler) override
Definition: REPL.cpp:111
static lldb::REPLSP Create(Status &Status, lldb::LanguageType language, Debugger *debugger, Target *target, const char *repl_options)
Get a REPL with an existing target (or, failing that, a debugger to use), and (optional) extra argume...
Definition: REPL.cpp:38
std::string m_indent_str
Definition: REPL.h:160
ConstString IOHandlerGetControlSequence(char ch) override
Definition: REPL.cpp:120
virtual bool PrintOneVariable(Debugger &debugger, lldb::StreamFileSP &output_sp, lldb::ValueObjectSP &valobj_sp, ExpressionVariable *var=nullptr)=0
void IOHandlerComplete(IOHandler &io_handler, CompletionRequest &request) override
Definition: REPL.cpp:496
OptionGroupFormat m_format_options
Definition: REPL.h:154
EvaluateExpressionOptions m_expr_options
Definition: REPL.h:156
bool IOHandlerIsInputComplete(IOHandler &io_handler, StringList &lines) override
Called to determine whether typing enter after the last line in lines should end input.
Definition: REPL.cpp:140
std::string GetSourcePath()
Definition: REPL.cpp:59
bool m_enable_auto_indent
Definition: REPL.h:159
virtual ConstString GetSourceFileBasename()=0
virtual bool SourceIsComplete(const std::string &source)=0
const char * IOHandlerGetCommandPrefix() override
Definition: REPL.cpp:126
Status RunLoop()
Definition: REPL.cpp:561
void IOHandlerInputInterrupted(IOHandler &io_handler, std::string &line) override
Definition: REPL.cpp:113
void IOHandlerActivated(IOHandler &io_handler, bool interactive) override
Definition: REPL.cpp:102
virtual lldb::LanguageType GetLanguage()=0
void IOHandlerInputComplete(IOHandler &io_handler, std::string &line) override
Called when a line or lines have been retrieved.
Definition: REPL.cpp:220
lldb::IOHandlerSP m_io_handler_sp
Definition: REPL.h:170
StringList m_code
Definition: REPL.h:167
std::string m_repl_source_path
Definition: REPL.h:164
lldb::IOHandlerSP GetIOHandler()
Definition: REPL.cpp:73
bool m_dedicated_repl_mode
Definition: REPL.h:165
virtual void CompleteCode(const std::string &current_code, CompletionRequest &request)=0
Target & m_target
Definition: REPL.h:169
virtual llvm::Error OnExpressionEvaluated(const ExecutionContext &exe_ctx, llvm::StringRef code, const EvaluateExpressionOptions &expr_options, lldb::ExpressionResults execution_results, const lldb::ValueObjectSP &result_valobj_sp, const Status &error)
Method that can be optionally overriden by subclasses to get notified whenever an expression has been...
Definition: REPL.h:120
bool SetDefaultFileAndLine(const FileSpec &file_spec, uint32_t line)
bool GetDefaultFileAndLine(FileSpec &file_spec, uint32_t &line)
An error handling class.
Definition: Status.h:44
bool Success() const
Test for success condition.
Definition: Status.cpp:287
std::string CopyList(const char *item_preamble=nullptr, const char *items_sep="\n") const
Definition: StringList.cpp:198
size_t SplitIntoLines(const std::string &lines)
Definition: StringList.cpp:152
void AppendString(const std::string &s)
Definition: StringList.cpp:43
const char * GetStringAtIndex(size_t idx) const
Definition: StringList.cpp:86
size_t GetSize() const
Definition: StringList.cpp:74
SourceManager & GetSourceManager()
Definition: Target.cpp:2721
PersistentExpressionState * GetPersistentExpressionStateForLanguage(lldb::LanguageType language)
Definition: Target.cpp:2406
Debugger & GetDebugger()
Definition: Target.h:1037
const lldb::ProcessSP & GetProcessSP() const
Definition: Target.cpp:219
Status UnwindInnermostExpression()
Unwinds the thread stack for the innermost expression plan currently on the thread plan stack.
Definition: Thread.cpp:1219
lldb::StackFrameSP GetSelectedFrame(SelectMostRelevant select_most_relevant)
Definition: Thread.cpp:263
bool SetSelectedFrameByIndex(uint32_t frame_idx, bool broadcast=false)
Definition: Thread.cpp:280
static const Status::ValueType kNoResult
ValueObject::GetError() returns this if there is no result from the expression.
static lldb::ExpressionResults Evaluate(ExecutionContext &exe_ctx, const EvaluateExpressionOptions &options, llvm::StringRef expr_cstr, llvm::StringRef expr_prefix, lldb::ValueObjectSP &result_valobj_sp, Status &error, std::string *fixed_expression=nullptr, ValueObject *ctx_obj=nullptr)
Evaluate one expression in the scratch context of the target passed in the exe_ctx and return its res...
#define LLDB_INVALID_OFFSET
Definition: lldb-defines.h:85
@ DoNoSelectMostRelevantFrame
A class that represents a running process on the host machine.
Definition: SBAttachInfo.h:14
Format
Display format definitions.
@ eFormatVoid
Do not print this.
uint64_t offset_t
Definition: lldb-types.h:83
LanguageType
Programming language type.
ExpressionResults
The results of expression evaluation.
@ eExpressionTimedOut
@ eExpressionCompleted
@ eExpressionHitBreakpoint
@ eExpressionInterrupted
@ eExpressionDiscarded
@ eExpressionParseError
@ eExpressionStoppedForDebug
@ eExpressionResultUnavailable
@ eExpressionThreadVanished
@ eExpressionSetupError
@ eReturnStatusQuit
A SmallBitVector that represents a set of source languages (lldb::LanguageType).
Definition: TypeSystem.h:45