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