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
25REPL::REPL(LLVMCastKind kind, Target &target) : m_target(target), m_kind(kind) {
26 // Make sure all option values have sane defaults
27 Debugger &debugger = m_target.GetDebugger();
28 debugger.SetShowProgress(false);
29 auto exe_ctx = debugger.GetCommandInterpreter().GetExecutionContext();
32}
33
34REPL::~REPL() = default;
35
36lldb::REPLSP REPL::Create(Status &err, lldb::LanguageType language,
37 Debugger *debugger, Target *target,
38 const char *repl_options) {
39 uint32_t idx = 0;
40 lldb::REPLSP ret;
41
42 while (REPLCreateInstance create_instance =
44 LanguageSet supported_languages =
46 if (!supported_languages[language])
47 continue;
48 ret = (*create_instance)(err, language, debugger, target, repl_options);
49 if (ret) {
50 break;
51 }
52 }
53
54 return ret;
55}
56
57std::string REPL::GetSourcePath() {
58 ConstString file_basename = GetSourceFileBasename();
59 FileSpec tmpdir_file_spec = HostInfo::GetProcessTempDir();
60 if (tmpdir_file_spec) {
61 tmpdir_file_spec.SetFilename(file_basename);
62 m_repl_source_path = tmpdir_file_spec.GetPath();
63 } else {
64 tmpdir_file_spec = FileSpec("/tmp");
65 tmpdir_file_spec.AppendPathComponent(file_basename.GetStringRef());
66 }
67
68 return tmpdir_file_spec.GetPath();
69}
70
71lldb::IOHandlerSP REPL::GetIOHandler() {
72 if (!m_io_handler_sp) {
73 Debugger &debugger = m_target.GetDebugger();
74 m_io_handler_sp = std::make_shared<IOHandlerEditline>(
75 debugger, IOHandler::Type::REPL,
76 "lldb-repl", // Name of input reader for history
77 llvm::StringRef("> "), // prompt
78 llvm::StringRef(". "), // Continuation prompt
79 true, // Multi-line
80 true, // The REPL prompt is always colored
81 1, // Line number
82 *this);
83
84 // Don't exit if CTRL+C is pressed
85 static_cast<IOHandlerEditline *>(m_io_handler_sp.get())
86 ->SetInterruptExits(false);
87
88 if (m_io_handler_sp->GetIsInteractive() &&
89 m_io_handler_sp->GetIsRealTerminal()) {
90 m_indent_str.assign(debugger.GetTabSize(), ' ');
92 } else {
93 m_indent_str.clear();
95 }
96 }
97 return m_io_handler_sp;
98}
99
100void REPL::IOHandlerActivated(IOHandler &io_handler, bool interactive) {
101 lldb::ProcessSP process_sp = m_target.GetProcessSP();
102 if (process_sp && process_sp->IsAlive())
103 return;
104 lldb::StreamFileSP error_sp(io_handler.GetErrorStreamFileSP());
105 error_sp->Printf("REPL requires a running target process.\n");
106 io_handler.SetIsDone(true);
107}
108
109bool REPL::IOHandlerInterrupt(IOHandler &io_handler) { return false; }
110
111void REPL::IOHandlerInputInterrupted(IOHandler &io_handler, std::string &line) {
112}
113
115 return (m_enable_auto_indent ? GetAutoIndentCharacters() : nullptr);
116}
117
119 if (ch == 'd')
120 return ConstString(":quit\n");
121 return ConstString();
122}
123
124const char *REPL::IOHandlerGetCommandPrefix() { return ":"; }
125
127 return "\nThe REPL (Read-Eval-Print-Loop) acts like an interpreter. "
128 "Valid statements, expressions, and declarations are immediately "
129 "compiled and executed.\n\n"
130 "The complete set of LLDB debugging commands are also available as "
131 "described below.\n\nCommands "
132 "must be prefixed with a colon at the REPL prompt (:quit for "
133 "example.) Typing just a colon "
134 "followed by return will switch to the LLDB prompt.\n\n"
135 "Type “< path” to read in code from a text file “path”.\n\n";
136}
137
139 // Check for meta command
140 const size_t num_lines = lines.GetSize();
141 if (num_lines == 1) {
142 const char *first_line = lines.GetStringAtIndex(0);
143 if (first_line[0] == ':')
144 return true; // Meta command is a single line where that starts with ':'
145 }
146
147 // Check if REPL input is done
148 std::string source_string(lines.CopyList());
149 return SourceIsComplete(source_string);
150}
151
153 std::string last_line = lines[lines.GetSize() - 1];
154
155 int actual_indent = 0;
156 for (char &ch : last_line) {
157 if (ch != ' ')
158 break;
159 ++actual_indent;
160 }
161
162 return actual_indent;
163}
164
166 const StringList &lines,
167 int cursor_position) {
169 return 0;
170
171 if (!lines.GetSize()) {
172 return 0;
173 }
174
175 int tab_size = io_handler.GetDebugger().GetTabSize();
176
177 lldb::offset_t desired_indent =
178 GetDesiredIndentation(lines, cursor_position, tab_size);
179
180 int actual_indent = REPL::CalculateActualIndentation(lines);
181
182 if (desired_indent == LLDB_INVALID_OFFSET)
183 return 0;
184
185 return (int)desired_indent - actual_indent;
186}
187
188static bool ReadCode(const std::string &path, std::string &code,
189 lldb::StreamFileSP &error_sp) {
190 auto &fs = FileSystem::Instance();
191 llvm::Twine pathTwine(path);
192 if (!fs.Exists(pathTwine)) {
193 error_sp->Printf("no such file at path '%s'\n", path.c_str());
194 return false;
195 }
196 if (!fs.Readable(pathTwine)) {
197 error_sp->Printf("could not read file at path '%s'\n", path.c_str());
198 return false;
199 }
200 const size_t file_size = fs.GetByteSize(pathTwine);
201 const size_t max_size = code.max_size();
202 if (file_size > max_size) {
203 error_sp->Printf("file at path '%s' too large: "
204 "file_size = %zu, max_size = %zu\n",
205 path.c_str(), file_size, max_size);
206 return false;
207 }
208 auto data_sp = fs.CreateDataBuffer(pathTwine);
209 if (data_sp == nullptr) {
210 error_sp->Printf("could not create buffer for file at path '%s'\n",
211 path.c_str());
212 return false;
213 }
214 code.assign((const char *)data_sp->GetBytes(), data_sp->GetByteSize());
215 return true;
216}
217
218void REPL::IOHandlerInputComplete(IOHandler &io_handler, std::string &code) {
219 lldb::StreamFileSP output_sp(io_handler.GetOutputStreamFileSP());
220 lldb::StreamFileSP error_sp(io_handler.GetErrorStreamFileSP());
221 bool extra_line = false;
222 bool did_quit = false;
223
224 if (code.empty()) {
226 static_cast<IOHandlerEditline &>(io_handler)
227 .SetBaseLineNumber(m_code.GetSize() + 1);
228 } else {
229 Debugger &debugger = m_target.GetDebugger();
231 extra_line = ci.GetSpaceReplPrompts();
232
234 ->GetThreadList()
235 .GetSelectedThread()
236 ->GetSelectedFrame()
237 .get());
238
239 lldb::ProcessSP process_sp(exe_ctx.GetProcessSP());
240
241 if (code[0] == ':') {
242 // Meta command
243 // Strip the ':'
244 code.erase(0, 1);
245 if (!llvm::StringRef(code).trim().empty()) {
246 // "lldb" was followed by arguments, so just execute the command dump
247 // the results
248
249 // Turn off prompt on quit in case the user types ":quit"
250 const bool saved_prompt_on_quit = ci.GetPromptOnQuit();
251 if (saved_prompt_on_quit)
252 ci.SetPromptOnQuit(false);
253
254 // Execute the command
255 CommandReturnObject result(debugger.GetUseColor());
256 result.SetImmediateOutputStream(output_sp);
257 result.SetImmediateErrorStream(error_sp);
258 ci.HandleCommand(code.c_str(), eLazyBoolNo, result);
259
260 if (saved_prompt_on_quit)
261 ci.SetPromptOnQuit(true);
262
263 if (result.GetStatus() == lldb::eReturnStatusQuit) {
264 did_quit = true;
265 io_handler.SetIsDone(true);
266 if (debugger.CheckTopIOHandlerTypes(
268 // We typed "quit" or an alias to quit so we need to check if the
269 // command interpreter is above us and tell it that it is done as
270 // well so we don't drop back into the command interpreter if we
271 // have already quit
272 lldb::IOHandlerSP io_handler_sp(ci.GetIOHandler());
273 if (io_handler_sp)
274 io_handler_sp->SetIsDone(true);
275 }
276 }
277 } else {
278 // ":" was followed by no arguments, so push the LLDB command prompt
279 if (debugger.CheckTopIOHandlerTypes(
281 // If the user wants to get back to the command interpreter and the
282 // command interpreter is what launched the REPL, then just let the
283 // REPL exit and fall back to the command interpreter.
284 io_handler.SetIsDone(true);
285 } else {
286 // The REPL wasn't launched the by the command interpreter, it is the
287 // base IOHandler, so we need to get the command interpreter and
288 lldb::IOHandlerSP io_handler_sp(ci.GetIOHandler());
289 if (io_handler_sp) {
290 io_handler_sp->SetIsDone(false);
291 debugger.RunIOHandlerAsync(ci.GetIOHandler());
292 }
293 }
294 }
295 } else {
296 if (code[0] == '<') {
297 // User wants to read code from a file.
298 // Interpret rest of line as a literal path.
299 auto path = llvm::StringRef(code.substr(1)).trim().str();
300 if (!ReadCode(path, code, error_sp)) {
301 return;
302 }
303 }
304
305 // Unwind any expression we might have been running in case our REPL
306 // expression crashed and the user was looking around
308 Thread *thread = exe_ctx.GetThreadPtr();
309 if (thread && thread->UnwindInnermostExpression().Success()) {
310 thread->SetSelectedFrameByIndex(0, false);
311 exe_ctx.SetFrameSP(thread->GetSelectedFrame());
312 }
313 }
314
315 const bool colorize_err = error_sp->GetFile().GetIsTerminalWithColors();
316
319 expr_options.SetKeepInMemory(true);
321 expr_options.SetGenerateDebugInfo(true);
322 expr_options.SetREPLEnabled(true);
323 expr_options.SetColorizeErrors(colorize_err);
324 expr_options.SetPoundLine(m_repl_source_path.c_str(),
325 m_code.GetSize() + 1);
326
327 expr_options.SetLanguage(GetLanguage());
328
329 PersistentExpressionState *persistent_state =
331 if (!persistent_state)
332 return;
333
334 const size_t var_count_before = persistent_state->GetSize();
335
336 const char *expr_prefix = nullptr;
337 lldb::ValueObjectSP result_valobj_sp;
339 lldb::ExpressionResults execution_results =
340 UserExpression::Evaluate(exe_ctx, expr_options, code.c_str(),
341 expr_prefix, result_valobj_sp, error,
342 nullptr); // fixed expression
343
344 // CommandInterpreter &ci = debugger.GetCommandInterpreter();
345
346 if (process_sp && process_sp->IsAlive()) {
347 bool add_to_code = true;
348 bool handled = false;
349 if (result_valobj_sp) {
351
352 if (result_valobj_sp->GetError().Success()) {
353 handled |= PrintOneVariable(debugger, output_sp, result_valobj_sp);
354 } else if (result_valobj_sp->GetError().GetError() ==
356 if (format != lldb::eFormatVoid && debugger.GetNotifyVoid()) {
357 error_sp->PutCString("(void)\n");
358 handled = true;
359 }
360 }
361 }
362
363 if (debugger.GetPrintDecls()) {
364 for (size_t vi = var_count_before, ve = persistent_state->GetSize();
365 vi != ve; ++vi) {
366 lldb::ExpressionVariableSP persistent_var_sp =
367 persistent_state->GetVariableAtIndex(vi);
368 lldb::ValueObjectSP valobj_sp = persistent_var_sp->GetValueObject();
369
370 PrintOneVariable(debugger, output_sp, valobj_sp,
371 persistent_var_sp.get());
372 }
373 }
374
375 if (!handled) {
376 bool useColors = error_sp->GetFile().GetIsTerminalWithColors();
377 switch (execution_results) {
380 add_to_code = false;
381 [[fallthrough]];
383 error_sp->Printf("%s\n", error.AsCString());
384 break;
385
387 break;
389 if (useColors) {
390 error_sp->Printf(ANSI_ESCAPE1(ANSI_FG_COLOR_RED));
391 error_sp->Printf(ANSI_ESCAPE1(ANSI_CTRL_BOLD));
392 }
393 error_sp->Printf("Execution interrupted. ");
394 if (useColors)
395 error_sp->Printf(ANSI_ESCAPE1(ANSI_CTRL_NORMAL));
396 error_sp->Printf("Enter code to recover and continue.\nEnter LLDB "
397 "commands to investigate (type :help for "
398 "assistance.)\n");
399 break;
400
402 // Breakpoint was hit, drop into LLDB command interpreter
403 if (useColors) {
404 error_sp->Printf(ANSI_ESCAPE1(ANSI_FG_COLOR_RED));
405 error_sp->Printf(ANSI_ESCAPE1(ANSI_CTRL_BOLD));
406 }
407 output_sp->Printf("Execution stopped at breakpoint. ");
408 if (useColors)
409 error_sp->Printf(ANSI_ESCAPE1(ANSI_CTRL_NORMAL));
410 output_sp->Printf("Enter LLDB commands to investigate (type help "
411 "for assistance.)\n");
412 {
413 lldb::IOHandlerSP io_handler_sp(ci.GetIOHandler());
414 if (io_handler_sp) {
415 io_handler_sp->SetIsDone(false);
416 debugger.RunIOHandlerAsync(ci.GetIOHandler());
417 }
418 }
419 break;
420
422 error_sp->Printf("error: timeout\n");
423 if (error.AsCString())
424 error_sp->Printf("error: %s\n", error.AsCString());
425 break;
427 // Shoulnd't happen???
428 error_sp->Printf("error: could not fetch result -- %s\n",
429 error.AsCString());
430 break;
432 // Shoulnd't happen???
433 error_sp->Printf("error: stopped for debug -- %s\n",
434 error.AsCString());
435 break;
437 // Shoulnd't happen???
438 error_sp->Printf("error: expression thread vanished -- %s\n",
439 error.AsCString());
440 break;
441 }
442 }
443
444 if (add_to_code) {
445 const uint32_t new_default_line = m_code.GetSize() + 1;
446
448
449 // Update our code on disk
450 if (!m_repl_source_path.empty()) {
451 auto file = FileSystem::Instance().Open(
455 lldb::eFilePermissionsFileDefault);
456 if (file) {
457 std::string code(m_code.CopyList());
458 code.append(1, '\n');
459 size_t bytes_written = code.size();
460 file.get()->Write(code.c_str(), bytes_written);
461 file.get()->Close();
462 } else {
463 std::string message = llvm::toString(file.takeError());
464 error_sp->Printf("error: couldn't open %s: %s\n",
465 m_repl_source_path.c_str(), message.c_str());
466 }
467
468 // Now set the default file and line to the REPL source file
470 FileSpec(m_repl_source_path), new_default_line);
471 }
472 static_cast<IOHandlerEditline &>(io_handler)
473 .SetBaseLineNumber(m_code.GetSize() + 1);
474 }
475 if (extra_line) {
476 output_sp->Printf("\n");
477 }
478 }
479 }
480
481 // Don't complain about the REPL process going away if we are in the
482 // process of quitting.
483 if (!did_quit && (!process_sp || !process_sp->IsAlive())) {
484 error_sp->Printf(
485 "error: REPL process is no longer alive, exiting REPL\n");
486 io_handler.SetIsDone(true);
487 }
488 }
489}
490
492 CompletionRequest &request) {
493 // Complete an LLDB command if the first character is a colon...
494 if (request.GetRawLine().startswith(":")) {
495 Debugger &debugger = m_target.GetDebugger();
496
497 // auto complete LLDB commands
498 llvm::StringRef new_line = request.GetRawLine().drop_front();
499 CompletionResult sub_result;
500 CompletionRequest sub_request(new_line, request.GetRawCursorPos() - 1,
501 sub_result);
502 debugger.GetCommandInterpreter().HandleCompletion(sub_request);
503 StringList matches, descriptions;
504 sub_result.GetMatches(matches);
505 // Prepend command prefix that was excluded in the completion request.
506 if (request.GetCursorIndex() == 0)
507 for (auto &match : matches)
508 match.insert(0, 1, ':');
509 sub_result.GetDescriptions(descriptions);
510 request.AddCompletions(matches, descriptions);
511 return;
512 }
513
514 // Strip spaces from the line and see if we had only spaces
515 if (request.GetRawLine().trim().empty()) {
516 // Only spaces on this line, so just indent
518 return;
519 }
520
521 std::string current_code;
522 current_code.append(m_code.CopyList());
523
524 IOHandlerEditline &editline = static_cast<IOHandlerEditline &>(io_handler);
525 const StringList *current_lines = editline.GetCurrentLines();
526 if (current_lines) {
527 const uint32_t current_line_idx = editline.GetCurrentLineIndex();
528
529 if (current_line_idx < current_lines->GetSize()) {
530 for (uint32_t i = 0; i < current_line_idx; ++i) {
531 const char *line_cstr = current_lines->GetStringAtIndex(i);
532 if (line_cstr) {
533 current_code.append("\n");
534 current_code.append(line_cstr);
535 }
536 }
537 }
538 }
539
540 current_code.append("\n");
541 current_code += request.GetRawLine();
542
543 CompleteCode(current_code, request);
544}
545
546bool QuitCommandOverrideCallback(void *baton, const char **argv) {
547 Target *target = (Target *)baton;
548 lldb::ProcessSP process_sp(target->GetProcessSP());
549 if (process_sp) {
550 process_sp->Destroy(false);
551 process_sp->GetTarget().GetDebugger().ClearIOHandlers();
552 }
553 return false;
554}
555
558
561
562 if (!error.Success())
563 return error;
564
565 Debugger &debugger = m_target.GetDebugger();
566
567 lldb::IOHandlerSP io_handler_sp(GetIOHandler());
568
569 FileSpec save_default_file;
570 uint32_t save_default_line = 0;
571
572 if (!m_repl_source_path.empty()) {
573 // Save the current default file and line
575 save_default_line);
576 }
577
578 debugger.RunIOHandlerAsync(io_handler_sp);
579
580 // Check if we are in dedicated REPL mode where LLDB was start with the "--
581 // repl" option from the command line. Currently we know this by checking if
582 // the debugger already has a IOHandler thread.
583 if (!debugger.HasIOHandlerThread()) {
584 // The debugger doesn't have an existing IOHandler thread, so this must be
585 // dedicated REPL mode...
587 debugger.StartIOHandlerThread();
588 llvm::StringRef command_name_str("quit");
589 CommandObject *cmd_obj =
591 command_name_str);
592 if (cmd_obj) {
593 assert(command_name_str.empty());
595 }
596 }
597
598 // Wait for the REPL command interpreter to get popped
599 io_handler_sp->WaitForPop();
600
602 // If we were in dedicated REPL mode we would have started the IOHandler
603 // thread, and we should kill our process
604 lldb::ProcessSP process_sp = m_target.GetProcessSP();
605 if (process_sp && process_sp->IsAlive())
606 process_sp->Destroy(false);
607
608 // Wait for the IO handler thread to exit (TODO: don't do this if the IO
609 // handler thread already exists...)
610 debugger.JoinIOHandlerThread();
611 }
612
613 // Restore the default file and line
614 if (save_default_file && save_default_line != 0)
616 save_default_line);
617 return error;
618}
#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:188
bool QuitCommandOverrideCallback(void *baton, const char **argv)
Definition: REPL.cpp:546
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:201
A class to manage flag bits.
Definition: Debugger.h:77
bool SetShowProgress(bool show_progress)
Definition: Debugger.cpp:395
bool GetPrintDecls() const
Definition: Debugger.cpp:513
CommandInterpreter & GetCommandInterpreter()
Definition: Debugger.h:170
bool GetUseColor() const
Definition: Debugger.cpp:376
void RunIOHandlerAsync(const lldb::IOHandlerSP &reader_sp, bool cancel_top_handler=true)
Run the given IO handler and return immediately.
Definition: Debugger.cpp:1093
bool GetAutoIndent() const
Definition: Debugger.cpp:503
uint32_t GetTabSize() const
Definition: Debugger.cpp:523
bool CheckTopIOHandlerTypes(IOHandler::Type top_type, IOHandler::Type second_top_type)
Definition: Debugger.cpp:1063
bool GetNotifyVoid() const
Definition: Debugger.cpp:292
void SetLanguage(lldb::LanguageType language)
Definition: Target.h:305
void SetKeepInMemory(bool keep=true)
Definition: Target.h:334
void SetCoerceToId(bool coerce=true)
Definition: Target.h:320
void SetPoundLine(const char *path, uint32_t line) const
Definition: Target.h:400
void SetUseDynamic(lldb::DynamicValueType dynamic=lldb::eDynamicCanRunTarget)
Definition: Target.h:339
"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:453
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:126
static int CalculateActualIndentation(const StringList &lines)
Definition: REPL.cpp:152
REPL(LLVMCastKind kind, Target &target)
Definition: REPL.cpp:25
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:114
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:165
virtual const char * GetAutoIndentCharacters()=0
OptionGroupValueObjectDisplay m_varobj_options
Definition: REPL.h:137
bool IOHandlerInterrupt(IOHandler &io_handler) override
Definition: REPL.cpp:109
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:36
std::string m_indent_str
Definition: REPL.h:142
ConstString IOHandlerGetControlSequence(char ch) override
Definition: REPL.cpp:118
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:491
OptionGroupFormat m_format_options
Definition: REPL.h:136
EvaluateExpressionOptions m_expr_options
Definition: REPL.h:138
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:138
std::string GetSourcePath()
Definition: REPL.cpp:57
bool m_enable_auto_indent
Definition: REPL.h:141
virtual ConstString GetSourceFileBasename()=0
virtual bool SourceIsComplete(const std::string &source)=0
const char * IOHandlerGetCommandPrefix() override
Definition: REPL.cpp:124
Status RunLoop()
Definition: REPL.cpp:556
void IOHandlerInputInterrupted(IOHandler &io_handler, std::string &line) override
Definition: REPL.cpp:111
void IOHandlerActivated(IOHandler &io_handler, bool interactive) override
Definition: REPL.cpp:100
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:218
lldb::IOHandlerSP m_io_handler_sp
Definition: REPL.h:152
StringList m_code
Definition: REPL.h:149
std::string m_repl_source_path
Definition: REPL.h:146
lldb::IOHandlerSP GetIOHandler()
Definition: REPL.cpp:71
bool m_dedicated_repl_mode
Definition: REPL.h:147
virtual void CompleteCode(const std::string &current_code, CompletionRequest &request)=0
Target & m_target
Definition: REPL.h:151
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:2712
PersistentExpressionState * GetPersistentExpressionStateForLanguage(lldb::LanguageType language)
Definition: Target.cpp:2397
Debugger & GetDebugger()
Definition: Target.h:1029
const lldb::ProcessSP & GetProcessSP() const
Definition: Target.cpp:218
Status UnwindInnermostExpression()
Unwinds the thread stack for the innermost expression plan currently on the thread plan stack.
Definition: Thread.cpp:1243
lldb::StackFrameSP GetSelectedFrame()
Definition: Thread.cpp:267
bool SetSelectedFrameByIndex(uint32_t frame_idx, bool broadcast=false)
Definition: Thread.cpp:284
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
A class that represents a running process on the host machine.
Format
Display format definitions.
@ eFormatVoid
Do not print this.
uint64_t offset_t
Definition: lldb-types.h:87
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