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 
9 #include "lldb/Expression/REPL.h"
10 #include "lldb/Core/Debugger.h"
12 #include "lldb/Core/StreamFile.h"
15 #include "lldb/Host/HostInfo.h"
18 #include "lldb/Target/Thread.h"
20 
21 #include <memory>
22 
23 using namespace lldb_private;
24 
25 REPL::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  auto exe_ctx = debugger.GetCommandInterpreter().GetExecutionContext();
31 }
32 
33 REPL::~REPL() = default;
34 
35 lldb::REPLSP REPL::Create(Status &err, lldb::LanguageType language,
36  Debugger *debugger, Target *target,
37  const char *repl_options) {
38  uint32_t idx = 0;
39  lldb::REPLSP ret;
40 
41  while (REPLCreateInstance create_instance =
43  ret = (*create_instance)(err, language, debugger, target, repl_options);
44  if (ret) {
45  break;
46  }
47  }
48 
49  return ret;
50 }
51 
52 std::string REPL::GetSourcePath() {
53  ConstString file_basename = GetSourceFileBasename();
54  FileSpec tmpdir_file_spec = HostInfo::GetProcessTempDir();
55  if (tmpdir_file_spec) {
56  tmpdir_file_spec.GetFilename() = file_basename;
57  m_repl_source_path = tmpdir_file_spec.GetPath();
58  } else {
59  tmpdir_file_spec = FileSpec("/tmp");
60  tmpdir_file_spec.AppendPathComponent(file_basename.GetStringRef());
61  }
62 
63  return tmpdir_file_spec.GetPath();
64 }
65 
66 lldb::IOHandlerSP REPL::GetIOHandler() {
67  if (!m_io_handler_sp) {
68  Debugger &debugger = m_target.GetDebugger();
69  m_io_handler_sp = std::make_shared<IOHandlerEditline>(
70  debugger, IOHandler::Type::REPL,
71  "lldb-repl", // Name of input reader for history
72  llvm::StringRef("> "), // prompt
73  llvm::StringRef(". "), // Continuation prompt
74  true, // Multi-line
75  true, // The REPL prompt is always colored
76  1, // Line number
77  *this, nullptr);
78 
79  // Don't exit if CTRL+C is pressed
80  static_cast<IOHandlerEditline *>(m_io_handler_sp.get())
81  ->SetInterruptExits(false);
82 
83  if (m_io_handler_sp->GetIsInteractive() &&
84  m_io_handler_sp->GetIsRealTerminal()) {
85  m_indent_str.assign(debugger.GetTabSize(), ' ');
86  m_enable_auto_indent = debugger.GetAutoIndent();
87  } else {
88  m_indent_str.clear();
89  m_enable_auto_indent = false;
90  }
91  }
92  return m_io_handler_sp;
93 }
94 
95 void REPL::IOHandlerActivated(IOHandler &io_handler, bool interactive) {
96  lldb::ProcessSP process_sp = m_target.GetProcessSP();
97  if (process_sp && process_sp->IsAlive())
98  return;
99  lldb::StreamFileSP error_sp(io_handler.GetErrorStreamFileSP());
100  error_sp->Printf("REPL requires a running target process.\n");
101  io_handler.SetIsDone(true);
102 }
103 
104 bool REPL::IOHandlerInterrupt(IOHandler &io_handler) { return false; }
105 
106 void REPL::IOHandlerInputInterrupted(IOHandler &io_handler, std::string &line) {
107 }
108 
110  return (m_enable_auto_indent ? GetAutoIndentCharacters() : nullptr);
111 }
112 
114  if (ch == 'd')
115  return ConstString(":quit\n");
116  return ConstString();
117 }
118 
119 const char *REPL::IOHandlerGetCommandPrefix() { return ":"; }
120 
122  return "\nThe REPL (Read-Eval-Print-Loop) acts like an interpreter. "
123  "Valid statements, expressions, and declarations are immediately "
124  "compiled and executed.\n\n"
125  "The complete set of LLDB debugging commands are also available as "
126  "described below. Commands "
127  "must be prefixed with a colon at the REPL prompt (:quit for "
128  "example.) Typing just a colon "
129  "followed by return will switch to the LLDB prompt.\n\n";
130 }
131 
133  // Check for meta command
134  const size_t num_lines = lines.GetSize();
135  if (num_lines == 1) {
136  const char *first_line = lines.GetStringAtIndex(0);
137  if (first_line[0] == ':')
138  return true; // Meta command is a single line where that starts with ':'
139  }
140 
141  // Check if REPL input is done
142  std::string source_string(lines.CopyList());
143  return SourceIsComplete(source_string);
144 }
145 
147  std::string last_line = lines[lines.GetSize() - 1];
148 
149  int actual_indent = 0;
150  for (char &ch : last_line) {
151  if (ch != ' ')
152  break;
153  ++actual_indent;
154  }
155 
156  return actual_indent;
157 }
158 
160  const StringList &lines,
161  int cursor_position) {
163  return 0;
164 
165  if (!lines.GetSize()) {
166  return 0;
167  }
168 
169  int tab_size = io_handler.GetDebugger().GetTabSize();
170 
171  lldb::offset_t desired_indent =
172  GetDesiredIndentation(lines, cursor_position, tab_size);
173 
174  int actual_indent = REPL::CalculateActualIndentation(lines);
175 
176  if (desired_indent == LLDB_INVALID_OFFSET)
177  return 0;
178 
179  return (int)desired_indent - actual_indent;
180 }
181 
182 void REPL::IOHandlerInputComplete(IOHandler &io_handler, std::string &code) {
183  lldb::StreamFileSP output_sp(io_handler.GetOutputStreamFileSP());
184  lldb::StreamFileSP error_sp(io_handler.GetErrorStreamFileSP());
185  bool extra_line = false;
186  bool did_quit = false;
187 
188  if (code.empty()) {
189  m_code.AppendString("");
190  static_cast<IOHandlerEditline &>(io_handler)
191  .SetBaseLineNumber(m_code.GetSize() + 1);
192  } else {
193  Debugger &debugger = m_target.GetDebugger();
194  CommandInterpreter &ci = debugger.GetCommandInterpreter();
195  extra_line = ci.GetSpaceReplPrompts();
196 
198  ->GetThreadList()
199  .GetSelectedThread()
200  ->GetSelectedFrame()
201  .get());
202 
203  lldb::ProcessSP process_sp(exe_ctx.GetProcessSP());
204 
205  if (code[0] == ':') {
206  // Meta command
207  // Strip the ':'
208  code.erase(0, 1);
209  if (!llvm::StringRef(code).trim().empty()) {
210  // "lldb" was followed by arguments, so just execute the command dump
211  // the results
212 
213  // Turn off prompt on quit in case the user types ":quit"
214  const bool saved_prompt_on_quit = ci.GetPromptOnQuit();
215  if (saved_prompt_on_quit)
216  ci.SetPromptOnQuit(false);
217 
218  // Execute the command
219  CommandReturnObject result;
220  result.SetImmediateOutputStream(output_sp);
221  result.SetImmediateErrorStream(error_sp);
222  ci.HandleCommand(code.c_str(), eLazyBoolNo, result);
223 
224  if (saved_prompt_on_quit)
225  ci.SetPromptOnQuit(true);
226 
227  if (result.GetStatus() == lldb::eReturnStatusQuit) {
228  did_quit = true;
229  io_handler.SetIsDone(true);
230  if (debugger.CheckTopIOHandlerTypes(
232  // We typed "quit" or an alias to quit so we need to check if the
233  // command interpreter is above us and tell it that it is done as
234  // well so we don't drop back into the command interpreter if we
235  // have already quit
236  lldb::IOHandlerSP io_handler_sp(ci.GetIOHandler());
237  if (io_handler_sp)
238  io_handler_sp->SetIsDone(true);
239  }
240  }
241  } else {
242  // ":" was followed by no arguments, so push the LLDB command prompt
243  if (debugger.CheckTopIOHandlerTypes(
245  // If the user wants to get back to the command interpreter and the
246  // command interpreter is what launched the REPL, then just let the
247  // REPL exit and fall back to the command interpreter.
248  io_handler.SetIsDone(true);
249  } else {
250  // The REPL wasn't launched the by the command interpreter, it is the
251  // base IOHandler, so we need to get the command interpreter and
252  lldb::IOHandlerSP io_handler_sp(ci.GetIOHandler());
253  if (io_handler_sp) {
254  io_handler_sp->SetIsDone(false);
255  debugger.RunIOHandlerAsync(ci.GetIOHandler());
256  }
257  }
258  }
259  } else {
260  // Unwind any expression we might have been running in case our REPL
261  // expression crashed and the user was looking around
262  if (m_dedicated_repl_mode) {
263  Thread *thread = exe_ctx.GetThreadPtr();
264  if (thread && thread->UnwindInnermostExpression().Success()) {
265  thread->SetSelectedFrameByIndex(0, false);
266  exe_ctx.SetFrameSP(thread->GetSelectedFrame());
267  }
268  }
269 
270  const bool colorize_err = error_sp->GetFile().GetIsTerminalWithColors();
271 
274  expr_options.SetKeepInMemory(true);
276  expr_options.SetGenerateDebugInfo(true);
277  expr_options.SetREPLEnabled(true);
278  expr_options.SetColorizeErrors(colorize_err);
279  expr_options.SetPoundLine(m_repl_source_path.c_str(),
280  m_code.GetSize() + 1);
281 
282  expr_options.SetLanguage(GetLanguage());
283 
284  PersistentExpressionState *persistent_state =
286  if (!persistent_state)
287  return;
288 
289  const size_t var_count_before = persistent_state->GetSize();
290 
291  const char *expr_prefix = nullptr;
292  lldb::ValueObjectSP result_valobj_sp;
293  Status error;
294  lldb::ExpressionResults execution_results =
295  UserExpression::Evaluate(exe_ctx, expr_options, code.c_str(),
296  expr_prefix, result_valobj_sp, error,
297  nullptr); // fixed expression
298 
299  // CommandInterpreter &ci = debugger.GetCommandInterpreter();
300 
301  if (process_sp && process_sp->IsAlive()) {
302  bool add_to_code = true;
303  bool handled = false;
304  if (result_valobj_sp) {
306 
307  if (result_valobj_sp->GetError().Success()) {
308  handled |= PrintOneVariable(debugger, output_sp, result_valobj_sp);
309  } else if (result_valobj_sp->GetError().GetError() ==
311  if (format != lldb::eFormatVoid && debugger.GetNotifyVoid()) {
312  error_sp->PutCString("(void)\n");
313  handled = true;
314  }
315  }
316  }
317 
318  if (debugger.GetPrintDecls()) {
319  for (size_t vi = var_count_before, ve = persistent_state->GetSize();
320  vi != ve; ++vi) {
321  lldb::ExpressionVariableSP persistent_var_sp =
322  persistent_state->GetVariableAtIndex(vi);
323  lldb::ValueObjectSP valobj_sp = persistent_var_sp->GetValueObject();
324 
325  PrintOneVariable(debugger, output_sp, valobj_sp,
326  persistent_var_sp.get());
327  }
328  }
329 
330  if (!handled) {
331  bool useColors = error_sp->GetFile().GetIsTerminalWithColors();
332  switch (execution_results) {
335  add_to_code = false;
336  LLVM_FALLTHROUGH;
338  error_sp->Printf("%s\n", error.AsCString());
339  break;
340 
342  break;
344  if (useColors) {
345  error_sp->Printf(ANSI_ESCAPE1(ANSI_FG_COLOR_RED));
346  error_sp->Printf(ANSI_ESCAPE1(ANSI_CTRL_BOLD));
347  }
348  error_sp->Printf("Execution interrupted. ");
349  if (useColors)
350  error_sp->Printf(ANSI_ESCAPE1(ANSI_CTRL_NORMAL));
351  error_sp->Printf("Enter code to recover and continue.\nEnter LLDB "
352  "commands to investigate (type :help for "
353  "assistance.)\n");
354  break;
355 
357  // Breakpoint was hit, drop into LLDB command interpreter
358  if (useColors) {
359  error_sp->Printf(ANSI_ESCAPE1(ANSI_FG_COLOR_RED));
360  error_sp->Printf(ANSI_ESCAPE1(ANSI_CTRL_BOLD));
361  }
362  output_sp->Printf("Execution stopped at breakpoint. ");
363  if (useColors)
364  error_sp->Printf(ANSI_ESCAPE1(ANSI_CTRL_NORMAL));
365  output_sp->Printf("Enter LLDB commands to investigate (type help "
366  "for assistance.)\n");
367  {
368  lldb::IOHandlerSP io_handler_sp(ci.GetIOHandler());
369  if (io_handler_sp) {
370  io_handler_sp->SetIsDone(false);
371  debugger.RunIOHandlerAsync(ci.GetIOHandler());
372  }
373  }
374  break;
375 
377  error_sp->Printf("error: timeout\n");
378  if (error.AsCString())
379  error_sp->Printf("error: %s\n", error.AsCString());
380  break;
382  // Shoulnd't happen???
383  error_sp->Printf("error: could not fetch result -- %s\n",
384  error.AsCString());
385  break;
387  // Shoulnd't happen???
388  error_sp->Printf("error: stopped for debug -- %s\n",
389  error.AsCString());
390  break;
392  // Shoulnd't happen???
393  error_sp->Printf("error: expression thread vanished -- %s\n",
394  error.AsCString());
395  break;
396  }
397  }
398 
399  if (add_to_code) {
400  const uint32_t new_default_line = m_code.GetSize() + 1;
401 
402  m_code.SplitIntoLines(code);
403 
404  // Update our code on disk
405  if (!m_repl_source_path.empty()) {
406  auto file = FileSystem::Instance().Open(
410  lldb::eFilePermissionsFileDefault);
411  if (file) {
412  std::string code(m_code.CopyList());
413  code.append(1, '\n');
414  size_t bytes_written = code.size();
415  file.get()->Write(code.c_str(), bytes_written);
416  file.get()->Close();
417  } else {
418  std::string message = llvm::toString(file.takeError());
419  error_sp->Printf("error: couldn't open %s: %s\n",
420  m_repl_source_path.c_str(), message.c_str());
421  }
422 
423  // Now set the default file and line to the REPL source file
425  FileSpec(m_repl_source_path), new_default_line);
426  }
427  static_cast<IOHandlerEditline &>(io_handler)
428  .SetBaseLineNumber(m_code.GetSize() + 1);
429  }
430  if (extra_line) {
431  output_sp->Printf("\n");
432  }
433  }
434  }
435 
436  // Don't complain about the REPL process going away if we are in the
437  // process of quitting.
438  if (!did_quit && (!process_sp || !process_sp->IsAlive())) {
439  error_sp->Printf(
440  "error: REPL process is no longer alive, exiting REPL\n");
441  io_handler.SetIsDone(true);
442  }
443  }
444 }
445 
447  CompletionRequest &request) {
448  // Complete an LLDB command if the first character is a colon...
449  if (request.GetRawLine().startswith(":")) {
450  Debugger &debugger = m_target.GetDebugger();
451 
452  // auto complete LLDB commands
453  llvm::StringRef new_line = request.GetRawLine().drop_front();
454  CompletionResult sub_result;
455  CompletionRequest sub_request(new_line, request.GetRawCursorPos() - 1,
456  sub_result);
457  debugger.GetCommandInterpreter().HandleCompletion(sub_request);
458  StringList matches, descriptions;
459  sub_result.GetMatches(matches);
460  sub_result.GetDescriptions(descriptions);
461  request.AddCompletions(matches, descriptions);
462  return;
463  }
464 
465  // Strip spaces from the line and see if we had only spaces
466  if (request.GetRawLine().trim().empty()) {
467  // Only spaces on this line, so just indent
468  request.AddCompletion(m_indent_str);
469  return;
470  }
471 
472  std::string current_code;
473  current_code.append(m_code.CopyList());
474 
475  IOHandlerEditline &editline = static_cast<IOHandlerEditline &>(io_handler);
476  const StringList *current_lines = editline.GetCurrentLines();
477  if (current_lines) {
478  const uint32_t current_line_idx = editline.GetCurrentLineIndex();
479 
480  if (current_line_idx < current_lines->GetSize()) {
481  for (uint32_t i = 0; i < current_line_idx; ++i) {
482  const char *line_cstr = current_lines->GetStringAtIndex(i);
483  if (line_cstr) {
484  current_code.append("\n");
485  current_code.append(line_cstr);
486  }
487  }
488  }
489  }
490 
491  current_code.append("\n");
492  current_code += request.GetRawLine();
493 
494  CompleteCode(current_code, request);
495 }
496 
497 bool QuitCommandOverrideCallback(void *baton, const char **argv) {
498  Target *target = (Target *)baton;
499  lldb::ProcessSP process_sp(target->GetProcessSP());
500  if (process_sp) {
501  process_sp->Destroy(false);
502  process_sp->GetTarget().GetDebugger().ClearIOHandlers();
503  }
504  return false;
505 }
506 
508  Status error;
509 
510  error = DoInitialization();
512 
513  if (!error.Success())
514  return error;
515 
516  Debugger &debugger = m_target.GetDebugger();
517 
518  lldb::IOHandlerSP io_handler_sp(GetIOHandler());
519 
520  FileSpec save_default_file;
521  uint32_t save_default_line = 0;
522 
523  if (!m_repl_source_path.empty()) {
524  // Save the current default file and line
525  m_target.GetSourceManager().GetDefaultFileAndLine(save_default_file,
526  save_default_line);
527  }
528 
529  debugger.RunIOHandlerAsync(io_handler_sp);
530 
531  // Check if we are in dedicated REPL mode where LLDB was start with the "--
532  // repl" option from the command line. Currently we know this by checking if
533  // the debugger already has a IOHandler thread.
534  if (!debugger.HasIOHandlerThread()) {
535  // The debugger doesn't have an existing IOHandler thread, so this must be
536  // dedicated REPL mode...
537  m_dedicated_repl_mode = true;
538  debugger.StartIOHandlerThread();
539  llvm::StringRef command_name_str("quit");
540  CommandObject *cmd_obj =
542  command_name_str);
543  if (cmd_obj) {
544  assert(command_name_str.empty());
546  }
547  }
548 
549  // Wait for the REPL command interpreter to get popped
550  io_handler_sp->WaitForPop();
551 
552  if (m_dedicated_repl_mode) {
553  // If we were in dedicated REPL mode we would have started the IOHandler
554  // thread, and we should kill our process
555  lldb::ProcessSP process_sp = m_target.GetProcessSP();
556  if (process_sp && process_sp->IsAlive())
557  process_sp->Destroy(false);
558 
559  // Wait for the IO handler thread to exit (TODO: don't do this if the IO
560  // handler thread already exists...)
561  debugger.JoinIOHandlerThread();
562  }
563 
564  // Restore the default file and line
565  if (save_default_file && save_default_line != 0)
566  m_target.GetSourceManager().SetDefaultFileAndLine(save_default_file,
567  save_default_line);
568  return error;
569 }
A class to manage flag bits.
Definition: Debugger.h:70
ConstString & GetFilename()
Filename string get accessor.
Definition: FileSpec.cpp:341
bool CheckTopIOHandlerTypes(IOHandler::Type top_type, IOHandler::Type second_top_type)
Definition: Debugger.cpp:914
virtual bool SourceIsComplete(const std::string &source)=0
lldb::IOHandlerSP m_io_handler_sp
Definition: REPL.h:152
llvm::StringRef GetRawLine() const
Returns the raw user input used to create this CompletionRequest cut off at the cursor position...
lldb::StackFrameSP GetSelectedFrame()
Definition: Thread.cpp:270
bool m_enable_auto_indent
Definition: REPL.h:141
const char * IOHandlerGetFixIndentationCharacters() override
Definition: REPL.cpp:109
uint32_t GetCurrentLineIndex() const
Definition: IOHandler.cpp:484
REPL(LLVMCastKind kind, Target &target)
Definition: REPL.cpp:25
A class that represents a running process on the host machine.
CommandInterpreter & GetCommandInterpreter()
Definition: Debugger.h:149
Status UnwindInnermostExpression()
Unwinds the thread stack for the innermost expression plan currently on the thread plan stack...
Definition: Thread.cpp:1217
lldb::StreamFileSP & GetErrorStreamFileSP()
Definition: IOHandler.cpp:109
virtual bool PrintOneVariable(Debugger &debugger, lldb::StreamFileSP &output_sp, lldb::ValueObjectSP &valobj_sp, ExpressionVariable *var=nullptr)=0
virtual const char * GetAutoIndentCharacters()=0
#define ANSI_FG_COLOR_RED
Definition: AnsiTerminal.h:14
void SetImmediateErrorStream(const lldb::StreamSP &stream_sp)
#define ANSI_CTRL_BOLD
Definition: AnsiTerminal.h:35
void SetUseDynamic(lldb::DynamicValueType dynamic=lldb::eDynamicCanRunTarget)
Definition: Target.h:300
void OptionParsingStarting(ExecutionContext *execution_context) override
const char * IOHandlerGetHelpPrologue() override
Definition: REPL.cpp:121
void AddCompletion(llvm::StringRef completion, llvm::StringRef description="", CompletionMode mode=CompletionMode::Normal)
Adds a possible completion string.
A file utility class.
Definition: FileSpec.h:56
bool GetNotifyVoid() const
Definition: Debugger.cpp:261
ConstString IOHandlerGetControlSequence(char ch) override
Definition: REPL.cpp:113
bool IOHandlerInterrupt(IOHandler &io_handler) override
Definition: REPL.cpp:104
void AddCompletions(const StringList &completions)
Adds multiple possible completion strings.
uint32_t GetTabSize() const
Definition: Debugger.cpp:445
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
void IOHandlerComplete(IOHandler &io_handler, CompletionRequest &request) override
Definition: REPL.cpp:446
void OptionParsingStarting(ExecutionContext *execution_context) override
bool m_dedicated_repl_mode
Definition: REPL.h:147
static int CalculateActualIndentation(const StringList &lines)
Definition: REPL.cpp:146
void IOHandlerInputInterrupted(IOHandler &io_handler, std::string &line) override
Definition: REPL.cpp:106
static FileSystem & Instance()
virtual lldb::offset_t GetDesiredIndentation(const StringList &lines, int cursor_position, int tab_size)=0
Format
Display format definitions.
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:35
void IOHandlerInputComplete(IOHandler &io_handler, std::string &line) override
Called when a line or lines have been retrieved.
Definition: REPL.cpp:182
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:159
std::string GetSourcePath()
Definition: REPL.cpp:52
#define LLDB_INVALID_OFFSET
Definition: lldb-defines.h:96
#define ANSI_CTRL_NORMAL
Definition: AnsiTerminal.h:34
"lldb/Utility/ArgCompletionRequest.h"
virtual lldb::LanguageType GetLanguage()=0
void SetKeepInMemory(bool keep=true)
Definition: Target.h:295
SourceManager & GetSourceManager()
Definition: Target.cpp:2459
LanguageType
Programming language type.
const lldb::ProcessSP & GetProcessSP() const
Definition: Target.cpp:206
llvm::StringRef toString(Record::Kind K)
static REPLCreateInstance GetREPLCreateCallbackAtIndex(uint32_t idx)
uint64_t offset_t
Definition: lldb-types.h:87
void AppendPathComponent(llvm::StringRef component)
Definition: FileSpec.cpp:435
const char * GetStringAtIndex(size_t idx) const
Definition: StringList.cpp:80
StringList m_code
Definition: REPL.h:149
lldb::StreamFileSP & GetOutputStreamFileSP()
Definition: IOHandler.cpp:107
const char * IOHandlerGetCommandPrefix() override
Definition: REPL.cpp:119
void SetImmediateOutputStream(const lldb::StreamSP &stream_sp)
const StringList * GetCurrentLines() const
Definition: IOHandler.h:408
bool GetPrintDecls() const
Definition: Debugger.cpp:435
lldb::IOHandlerSP GetIOHandler(bool force_create=false, CommandInterpreterRunOptions *options=nullptr)
#define ANSI_ESCAPE1(s)
Definition: AnsiTerminal.h:51
Do not print this.
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
Definition: ConstString.h:232
Debugger & GetDebugger()
Definition: IOHandler.h:135
bool Success() const
Test for success condition.
Definition: Status.cpp:288
static const Status::ValueType kNoResult
ValueObject::GetError() returns this if there is no result from the expression.
virtual void CompleteCode(const std::string &current_code, CompletionRequest &request)=0
std::string CopyList(const char *item_preamble=nullptr, const char *items_sep="\) const
Definition: StringList.cpp:192
lldb::ExpressionVariableSP GetVariableAtIndex(size_t index)
bool SetSelectedFrameByIndex(uint32_t frame_idx, bool broadcast=false)
Definition: Thread.cpp:287
void SetOverrideCallback(lldb::CommandOverrideCallback callback, void *baton)
bool SetDefaultFileAndLine(const FileSpec &file_spec, uint32_t line)
size_t GetSize()
Implementation of methods in ExpressionVariableListBase.
void GetMatches(StringList &matches) const
Adds all collected completion matches to the given list.
size_t GetSize() const
Definition: StringList.cpp:68
ExpressionResults
The results of expression evaluation.
void SetLanguage(lldb::LanguageType language)
Definition: Target.h:266
void HandleCompletion(CompletionRequest &request)
void SetCoerceToId(bool coerce=true)
Definition: Target.h:281
OptionGroupValueObjectDisplay m_varobj_options
Definition: REPL.h:137
EvaluateExpressionOptions m_expr_options
Definition: REPL.h:138
void GetDescriptions(StringList &descriptions) const
Adds all collected completion descriptions to the given list.
Target & m_target
Definition: REPL.h:151
lldb::IOHandlerSP GetIOHandler()
Definition: REPL.cpp:66
A uniqued constant string class.
Definition: ConstString.h:40
virtual Status DoInitialization()=0
virtual void SetIsDone(bool b)
Definition: IOHandler.h:88
bool HandleCommand(const char *command_line, LazyBool add_to_history, CommandReturnObject &result, ExecutionContext *override_context=nullptr, bool repeat_on_empty_command=true, bool no_context_switching=false)
OptionGroupFormat m_format_options
Definition: REPL.h:136
bool GetDefaultFileAndLine(FileSpec &file_spec, uint32_t &line)
Status RunLoop()
Definition: REPL.cpp:507
void IOHandlerActivated(IOHandler &io_handler, bool interactive) override
Definition: REPL.cpp:95
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:132
void SetPoundLine(const char *path, uint32_t line) const
Definition: Target.h:361
void RunIOHandlerAsync(const lldb::IOHandlerSP &reader_sp, bool cancel_top_handler=true)
Run the given IO handler and return immediately.
Definition: Debugger.cpp:941
size_t SplitIntoLines(const std::string &lines)
Definition: StringList.cpp:146
void AppendString(const std::string &s)
Definition: StringList.cpp:43
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition: FileSpec.cpp:348
CommandObject * GetCommandObjectForCommand(llvm::StringRef &command_line)
std::string m_indent_str
Definition: REPL.h:142
bool QuitCommandOverrideCallback(void *baton, const char **argv)
Definition: REPL.cpp:497
PersistentExpressionState * GetPersistentExpressionStateForLanguage(lldb::LanguageType language)
Definition: Target.cpp:2178
Debugger & GetDebugger()
Definition: Target.h:974
virtual ConstString GetSourceFileBasename()=0
std::string m_repl_source_path
Definition: REPL.h:146
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...
int Open(const char *path, int flags, int mode)
Wraps ::open in a platform-independent way.
An error handling class.
Definition: Status.h:44