xref: /llvm-project/lldb/source/Commands/CommandObjectExpression.cpp (revision b1ecc3cac29bdae5469e9610a1ff66f8531a503c)
1 //===-- CommandObjectExpression.cpp -----------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 // C Includes
11 // C++ Includes
12 // Other libraries and framework includes
13 #include "llvm/ADT/STLExtras.h"
14 #include "llvm/ADT/StringRef.h"
15 
16 // Project includes
17 #include "CommandObjectExpression.h"
18 #include "Plugins/ExpressionParser/Clang/ClangExpressionVariable.h"
19 #include "lldb/Core/Debugger.h"
20 #include "lldb/Core/Value.h"
21 #include "lldb/Core/ValueObjectVariable.h"
22 #include "lldb/DataFormatters/ValueObjectPrinter.h"
23 #include "lldb/Expression/DWARFExpression.h"
24 #include "lldb/Expression/REPL.h"
25 #include "lldb/Expression/UserExpression.h"
26 #include "lldb/Host/Host.h"
27 #include "lldb/Host/OptionParser.h"
28 #include "lldb/Interpreter/CommandInterpreter.h"
29 #include "lldb/Interpreter/CommandReturnObject.h"
30 #include "lldb/Interpreter/OptionArgParser.h"
31 #include "lldb/Symbol/ObjectFile.h"
32 #include "lldb/Symbol/Variable.h"
33 #include "lldb/Target/Language.h"
34 #include "lldb/Target/Process.h"
35 #include "lldb/Target/StackFrame.h"
36 #include "lldb/Target/Target.h"
37 #include "lldb/Target/Thread.h"
38 
39 using namespace lldb;
40 using namespace lldb_private;
41 
42 CommandObjectExpression::CommandOptions::CommandOptions() : OptionGroup() {}
43 
44 CommandObjectExpression::CommandOptions::~CommandOptions() = default;
45 
46 static constexpr OptionEnumValueElement g_description_verbosity_type[] = {
47     {eLanguageRuntimeDescriptionDisplayVerbosityCompact, "compact",
48      "Only show the description string"},
49     {eLanguageRuntimeDescriptionDisplayVerbosityFull, "full",
50      "Show the full output, including persistent variable's name and type"} };
51 
52 static constexpr OptionEnumValues DescriptionVerbosityTypes() {
53   return OptionEnumValues(g_description_verbosity_type);
54 }
55 
56 static constexpr OptionDefinition g_expression_options[] = {
57     // clang-format off
58   {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "all-threads",           'a', OptionParser::eRequiredArgument, nullptr, {},                          0, eArgTypeBoolean,              "Should we run all threads if the execution doesn't complete on one thread."},
59   {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "ignore-breakpoints",    'i', OptionParser::eRequiredArgument, nullptr, {},                          0, eArgTypeBoolean,              "Ignore breakpoint hits while running expressions"},
60   {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "timeout",               't', OptionParser::eRequiredArgument, nullptr, {},                          0, eArgTypeUnsignedInteger,      "Timeout value (in microseconds) for running the expression."},
61   {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "unwind-on-error",       'u', OptionParser::eRequiredArgument, nullptr, {},                          0, eArgTypeBoolean,              "Clean up program state if the expression causes a crash, or raises a signal.  "
62                                                                                                                                                                                   "Note, unlike gdb hitting a breakpoint is controlled by another option (-i)."},
63   {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "debug",                 'g', OptionParser::eNoArgument,       nullptr, {},                          0, eArgTypeNone,                 "When specified, debug the JIT code by setting a breakpoint on the first instruction "
64                                                                                                                                                                                   "and forcing breakpoints to not be ignored (-i0) and no unwinding to happen on error (-u0)."},
65   {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "language",              'l', OptionParser::eRequiredArgument, nullptr, {},                          0, eArgTypeLanguage,             "Specifies the Language to use when parsing the expression.  If not set the target.language "
66                                                                                                                                                                                   "setting is used." },
67   {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "apply-fixits",          'X', OptionParser::eRequiredArgument, nullptr, {},                          0, eArgTypeLanguage,             "If true, simple fix-it hints will be automatically applied to the expression." },
68   {LLDB_OPT_SET_1,                  false, "description-verbosity", 'v', OptionParser::eOptionalArgument, nullptr, DescriptionVerbosityTypes(), 0, eArgTypeDescriptionVerbosity, "How verbose should the output of this expression be, if the object description is asked for."},
69   {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "top-level",             'p', OptionParser::eNoArgument,       nullptr, {},                          0, eArgTypeNone,                 "Interpret the expression as a complete translation unit, without injecting it into the local "
70                                                                                                                                                                                   "context.  Allows declaration of persistent, top-level entities without a $ prefix."},
71   {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "allow-jit",             'j', OptionParser::eRequiredArgument, nullptr, {},                          0, eArgTypeBoolean,              "Controls whether the expression can fall back to being JITted if it's not supported by "
72                                                                                                                                                                                   "the interpreter (defaults to true)."}
73     // clang-format on
74 };
75 
76 Status CommandObjectExpression::CommandOptions::SetOptionValue(
77     uint32_t option_idx, llvm::StringRef option_arg,
78     ExecutionContext *execution_context) {
79   Status error;
80 
81   const int short_option = GetDefinitions()[option_idx].short_option;
82 
83   switch (short_option) {
84   case 'l':
85     language = Language::GetLanguageTypeFromString(option_arg);
86     if (language == eLanguageTypeUnknown)
87       error.SetErrorStringWithFormat(
88           "unknown language type: '%s' for expression",
89           option_arg.str().c_str());
90     break;
91 
92   case 'a': {
93     bool success;
94     bool result;
95     result = OptionArgParser::ToBoolean(option_arg, true, &success);
96     if (!success)
97       error.SetErrorStringWithFormat(
98           "invalid all-threads value setting: \"%s\"",
99           option_arg.str().c_str());
100     else
101       try_all_threads = result;
102   } break;
103 
104   case 'i': {
105     bool success;
106     bool tmp_value = OptionArgParser::ToBoolean(option_arg, true, &success);
107     if (success)
108       ignore_breakpoints = tmp_value;
109     else
110       error.SetErrorStringWithFormat(
111           "could not convert \"%s\" to a boolean value.",
112           option_arg.str().c_str());
113     break;
114   }
115 
116   case 'j': {
117     bool success;
118     bool tmp_value = OptionArgParser::ToBoolean(option_arg, true, &success);
119     if (success)
120       allow_jit = tmp_value;
121     else
122       error.SetErrorStringWithFormat(
123           "could not convert \"%s\" to a boolean value.",
124           option_arg.str().c_str());
125     break;
126   }
127 
128   case 't':
129     if (option_arg.getAsInteger(0, timeout)) {
130       timeout = 0;
131       error.SetErrorStringWithFormat("invalid timeout setting \"%s\"",
132                                      option_arg.str().c_str());
133     }
134     break;
135 
136   case 'u': {
137     bool success;
138     bool tmp_value = OptionArgParser::ToBoolean(option_arg, true, &success);
139     if (success)
140       unwind_on_error = tmp_value;
141     else
142       error.SetErrorStringWithFormat(
143           "could not convert \"%s\" to a boolean value.",
144           option_arg.str().c_str());
145     break;
146   }
147 
148   case 'v':
149     if (option_arg.empty()) {
150       m_verbosity = eLanguageRuntimeDescriptionDisplayVerbosityFull;
151       break;
152     }
153     m_verbosity = (LanguageRuntimeDescriptionDisplayVerbosity)
154         OptionArgParser::ToOptionEnum(
155             option_arg, GetDefinitions()[option_idx].enum_values, 0, error);
156     if (!error.Success())
157       error.SetErrorStringWithFormat(
158           "unrecognized value for description-verbosity '%s'",
159           option_arg.str().c_str());
160     break;
161 
162   case 'g':
163     debug = true;
164     unwind_on_error = false;
165     ignore_breakpoints = false;
166     break;
167 
168   case 'p':
169     top_level = true;
170     break;
171 
172   case 'X': {
173     bool success;
174     bool tmp_value = OptionArgParser::ToBoolean(option_arg, true, &success);
175     if (success)
176       auto_apply_fixits = tmp_value ? eLazyBoolYes : eLazyBoolNo;
177     else
178       error.SetErrorStringWithFormat(
179           "could not convert \"%s\" to a boolean value.",
180           option_arg.str().c_str());
181     break;
182   }
183 
184   default:
185     error.SetErrorStringWithFormat("invalid short option character '%c'",
186                                    short_option);
187     break;
188   }
189 
190   return error;
191 }
192 
193 void CommandObjectExpression::CommandOptions::OptionParsingStarting(
194     ExecutionContext *execution_context) {
195   auto process_sp =
196       execution_context ? execution_context->GetProcessSP() : ProcessSP();
197   if (process_sp) {
198     ignore_breakpoints = process_sp->GetIgnoreBreakpointsInExpressions();
199     unwind_on_error = process_sp->GetUnwindOnErrorInExpressions();
200   } else {
201     ignore_breakpoints = true;
202     unwind_on_error = true;
203   }
204 
205   show_summary = true;
206   try_all_threads = true;
207   timeout = 0;
208   debug = false;
209   language = eLanguageTypeUnknown;
210   m_verbosity = eLanguageRuntimeDescriptionDisplayVerbosityCompact;
211   auto_apply_fixits = eLazyBoolCalculate;
212   top_level = false;
213   allow_jit = true;
214 }
215 
216 llvm::ArrayRef<OptionDefinition>
217 CommandObjectExpression::CommandOptions::GetDefinitions() {
218   return llvm::makeArrayRef(g_expression_options);
219 }
220 
221 CommandObjectExpression::CommandObjectExpression(
222     CommandInterpreter &interpreter)
223     : CommandObjectRaw(
224           interpreter, "expression", "Evaluate an expression on the current "
225                                      "thread.  Displays any returned value "
226                                      "with LLDB's default formatting.",
227           "", eCommandProcessMustBePaused | eCommandTryTargetAPILock),
228       IOHandlerDelegate(IOHandlerDelegate::Completion::Expression),
229       m_option_group(), m_format_options(eFormatDefault),
230       m_repl_option(LLDB_OPT_SET_1, false, "repl", 'r', "Drop into REPL", false,
231                     true),
232       m_command_options(), m_expr_line_count(0), m_expr_lines() {
233   SetHelpLong(
234       R"(
235 Single and multi-line expressions:
236 
237 )"
238       "    The expression provided on the command line must be a complete expression \
239 with no newlines.  To evaluate a multi-line expression, \
240 hit a return after an empty expression, and lldb will enter the multi-line expression editor. \
241 Hit return on an empty line to end the multi-line expression."
242 
243       R"(
244 
245 Timeouts:
246 
247 )"
248       "    If the expression can be evaluated statically (without running code) then it will be.  \
249 Otherwise, by default the expression will run on the current thread with a short timeout: \
250 currently .25 seconds.  If it doesn't return in that time, the evaluation will be interrupted \
251 and resumed with all threads running.  You can use the -a option to disable retrying on all \
252 threads.  You can use the -t option to set a shorter timeout."
253       R"(
254 
255 User defined variables:
256 
257 )"
258       "    You can define your own variables for convenience or to be used in subsequent expressions.  \
259 You define them the same way you would define variables in C.  If the first character of \
260 your user defined variable is a $, then the variable's value will be available in future \
261 expressions, otherwise it will just be available in the current expression."
262       R"(
263 
264 Continuing evaluation after a breakpoint:
265 
266 )"
267       "    If the \"-i false\" option is used, and execution is interrupted by a breakpoint hit, once \
268 you are done with your investigation, you can either remove the expression execution frames \
269 from the stack with \"thread return -x\" or if you are still interested in the expression result \
270 you can issue the \"continue\" command and the expression evaluation will complete and the \
271 expression result will be available using the \"thread.completed-expression\" key in the thread \
272 format."
273 
274       R"(
275 
276 Examples:
277 
278     expr my_struct->a = my_array[3]
279     expr -f bin -- (index * 8) + 5
280     expr unsigned int $foo = 5
281     expr char c[] = \"foo\"; c[0])");
282 
283   CommandArgumentEntry arg;
284   CommandArgumentData expression_arg;
285 
286   // Define the first (and only) variant of this arg.
287   expression_arg.arg_type = eArgTypeExpression;
288   expression_arg.arg_repetition = eArgRepeatPlain;
289 
290   // There is only one variant this argument could be; put it into the argument
291   // entry.
292   arg.push_back(expression_arg);
293 
294   // Push the data for the first argument into the m_arguments vector.
295   m_arguments.push_back(arg);
296 
297   // Add the "--format" and "--gdb-format"
298   m_option_group.Append(&m_format_options,
299                         OptionGroupFormat::OPTION_GROUP_FORMAT |
300                             OptionGroupFormat::OPTION_GROUP_GDB_FMT,
301                         LLDB_OPT_SET_1);
302   m_option_group.Append(&m_command_options);
303   m_option_group.Append(&m_varobj_options, LLDB_OPT_SET_ALL,
304                         LLDB_OPT_SET_1 | LLDB_OPT_SET_2);
305   m_option_group.Append(&m_repl_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_3);
306   m_option_group.Finalize();
307 }
308 
309 CommandObjectExpression::~CommandObjectExpression() = default;
310 
311 Options *CommandObjectExpression::GetOptions() { return &m_option_group; }
312 
313 int CommandObjectExpression::HandleCompletion(CompletionRequest &request) {
314   EvaluateExpressionOptions options;
315   options.SetCoerceToId(m_varobj_options.use_objc);
316   options.SetLanguage(m_command_options.language);
317   options.SetExecutionPolicy(lldb_private::eExecutionPolicyNever);
318   options.SetAutoApplyFixIts(false);
319   options.SetGenerateDebugInfo(false);
320 
321   // We need a valid execution context with a frame pointer for this
322   // completion, so if we don't have one we should try to make a valid
323   // execution context.
324   if (m_interpreter.GetExecutionContext().GetFramePtr() == nullptr)
325     m_interpreter.UpdateExecutionContext(nullptr);
326 
327   // This didn't work, so let's get out before we start doing things that
328   // expect a valid frame pointer.
329   if (m_interpreter.GetExecutionContext().GetFramePtr() == nullptr)
330     return 0;
331 
332   ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
333 
334   Target *target = exe_ctx.GetTargetPtr();
335 
336   if (!target)
337     target = GetDummyTarget();
338 
339   if (!target)
340     return 0;
341 
342   unsigned cursor_pos = request.GetRawCursorPos();
343   llvm::StringRef code = request.GetRawLine();
344 
345   const std::size_t original_code_size = code.size();
346 
347   // Remove the first token which is 'expr' or some alias/abbreviation of that.
348   code = llvm::getToken(code).second.ltrim();
349   OptionsWithRaw args(code);
350   code = args.GetRawPart();
351 
352   // The position where the expression starts in the command line.
353   assert(original_code_size >= code.size());
354   std::size_t raw_start = original_code_size - code.size();
355 
356   // Check if the cursor is actually in the expression string, and if not, we
357   // exit.
358   // FIXME: We should complete the options here.
359   if (cursor_pos < raw_start)
360     return 0;
361 
362   // Make the cursor_pos again relative to the start of the code string.
363   assert(cursor_pos >= raw_start);
364   cursor_pos -= raw_start;
365 
366   auto language = exe_ctx.GetFrameRef().GetLanguage();
367 
368   Status error;
369   lldb::UserExpressionSP expr(target->GetUserExpressionForLanguage(
370       code, llvm::StringRef(), language, UserExpression::eResultTypeAny,
371       options, error));
372   if (error.Fail())
373     return 0;
374 
375   expr->Complete(exe_ctx, request, cursor_pos);
376   return request.GetNumberOfMatches();
377 }
378 
379 static lldb_private::Status
380 CanBeUsedForElementCountPrinting(ValueObject &valobj) {
381   CompilerType type(valobj.GetCompilerType());
382   CompilerType pointee;
383   if (!type.IsPointerType(&pointee))
384     return Status("as it does not refer to a pointer");
385   if (pointee.IsVoidType())
386     return Status("as it refers to a pointer to void");
387   return Status();
388 }
389 
390 bool CommandObjectExpression::EvaluateExpression(llvm::StringRef expr,
391                                                  Stream *output_stream,
392                                                  Stream *error_stream,
393                                                  CommandReturnObject *result) {
394   // Don't use m_exe_ctx as this might be called asynchronously after the
395   // command object DoExecute has finished when doing multi-line expression
396   // that use an input reader...
397   ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
398 
399   Target *target = exe_ctx.GetTargetPtr();
400 
401   if (!target)
402     target = GetDummyTarget();
403 
404   if (target) {
405     lldb::ValueObjectSP result_valobj_sp;
406     bool keep_in_memory = true;
407     StackFrame *frame = exe_ctx.GetFramePtr();
408 
409     EvaluateExpressionOptions options;
410     options.SetCoerceToId(m_varobj_options.use_objc);
411     options.SetUnwindOnError(m_command_options.unwind_on_error);
412     options.SetIgnoreBreakpoints(m_command_options.ignore_breakpoints);
413     options.SetKeepInMemory(keep_in_memory);
414     options.SetUseDynamic(m_varobj_options.use_dynamic);
415     options.SetTryAllThreads(m_command_options.try_all_threads);
416     options.SetDebug(m_command_options.debug);
417     options.SetLanguage(m_command_options.language);
418     options.SetExecutionPolicy(
419         m_command_options.allow_jit
420             ? EvaluateExpressionOptions::default_execution_policy
421             : lldb_private::eExecutionPolicyNever);
422 
423     bool auto_apply_fixits;
424     if (m_command_options.auto_apply_fixits == eLazyBoolCalculate)
425       auto_apply_fixits = target->GetEnableAutoApplyFixIts();
426     else
427       auto_apply_fixits =
428           m_command_options.auto_apply_fixits == eLazyBoolYes ? true : false;
429 
430     options.SetAutoApplyFixIts(auto_apply_fixits);
431 
432     if (m_command_options.top_level)
433       options.SetExecutionPolicy(eExecutionPolicyTopLevel);
434 
435     // If there is any chance we are going to stop and want to see what went
436     // wrong with our expression, we should generate debug info
437     if (!m_command_options.ignore_breakpoints ||
438         !m_command_options.unwind_on_error)
439       options.SetGenerateDebugInfo(true);
440 
441     if (m_command_options.timeout > 0)
442       options.SetTimeout(std::chrono::microseconds(m_command_options.timeout));
443     else
444       options.SetTimeout(llvm::None);
445 
446     ExpressionResults success = target->EvaluateExpression(
447         expr, frame, result_valobj_sp, options, &m_fixed_expression);
448 
449     // We only tell you about the FixIt if we applied it.  The compiler errors
450     // will suggest the FixIt if it parsed.
451     if (error_stream && !m_fixed_expression.empty() &&
452         target->GetEnableNotifyAboutFixIts()) {
453       if (success == eExpressionCompleted)
454         error_stream->Printf(
455             "  Fix-it applied, fixed expression was: \n    %s\n",
456             m_fixed_expression.c_str());
457     }
458 
459     if (result_valobj_sp) {
460       Format format = m_format_options.GetFormat();
461 
462       if (result_valobj_sp->GetError().Success()) {
463         if (format != eFormatVoid) {
464           if (format != eFormatDefault)
465             result_valobj_sp->SetFormat(format);
466 
467           if (m_varobj_options.elem_count > 0) {
468             Status error(CanBeUsedForElementCountPrinting(*result_valobj_sp));
469             if (error.Fail()) {
470               result->AppendErrorWithFormat(
471                   "expression cannot be used with --element-count %s\n",
472                   error.AsCString(""));
473               result->SetStatus(eReturnStatusFailed);
474               return false;
475             }
476           }
477 
478           DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions(
479               m_command_options.m_verbosity, format));
480           options.SetVariableFormatDisplayLanguage(
481               result_valobj_sp->GetPreferredDisplayLanguage());
482 
483           result_valobj_sp->Dump(*output_stream, options);
484 
485           if (result)
486             result->SetStatus(eReturnStatusSuccessFinishResult);
487         }
488       } else {
489         if (result_valobj_sp->GetError().GetError() ==
490             lldb::eExpressionProducedNoResult) {
491           if (format != eFormatVoid &&
492               m_interpreter.GetDebugger().GetNotifyVoid()) {
493             error_stream->PutCString("(void)\n");
494           }
495 
496           if (result)
497             result->SetStatus(eReturnStatusSuccessFinishResult);
498         } else {
499           const char *error_cstr = result_valobj_sp->GetError().AsCString();
500           if (error_cstr && error_cstr[0]) {
501             const size_t error_cstr_len = strlen(error_cstr);
502             const bool ends_with_newline =
503                 error_cstr[error_cstr_len - 1] == '\n';
504             if (strstr(error_cstr, "error:") != error_cstr)
505               error_stream->PutCString("error: ");
506             error_stream->Write(error_cstr, error_cstr_len);
507             if (!ends_with_newline)
508               error_stream->EOL();
509           } else {
510             error_stream->PutCString("error: unknown error\n");
511           }
512 
513           if (result)
514             result->SetStatus(eReturnStatusFailed);
515         }
516       }
517     }
518   } else {
519     error_stream->Printf("error: invalid execution context for expression\n");
520     return false;
521   }
522 
523   return true;
524 }
525 
526 void CommandObjectExpression::IOHandlerInputComplete(IOHandler &io_handler,
527                                                      std::string &line) {
528   io_handler.SetIsDone(true);
529   //    StreamSP output_stream =
530   //    io_handler.GetDebugger().GetAsyncOutputStream();
531   //    StreamSP error_stream = io_handler.GetDebugger().GetAsyncErrorStream();
532   StreamFileSP output_sp(io_handler.GetOutputStreamFile());
533   StreamFileSP error_sp(io_handler.GetErrorStreamFile());
534 
535   EvaluateExpression(line.c_str(), output_sp.get(), error_sp.get());
536   if (output_sp)
537     output_sp->Flush();
538   if (error_sp)
539     error_sp->Flush();
540 }
541 
542 bool CommandObjectExpression::IOHandlerIsInputComplete(IOHandler &io_handler,
543                                                        StringList &lines) {
544   // An empty lines is used to indicate the end of input
545   const size_t num_lines = lines.GetSize();
546   if (num_lines > 0 && lines[num_lines - 1].empty()) {
547     // Remove the last empty line from "lines" so it doesn't appear in our
548     // resulting input and return true to indicate we are done getting lines
549     lines.PopBack();
550     return true;
551   }
552   return false;
553 }
554 
555 void CommandObjectExpression::GetMultilineExpression() {
556   m_expr_lines.clear();
557   m_expr_line_count = 0;
558 
559   Debugger &debugger = GetCommandInterpreter().GetDebugger();
560   bool color_prompt = debugger.GetUseColor();
561   const bool multiple_lines = true; // Get multiple lines
562   IOHandlerSP io_handler_sp(
563       new IOHandlerEditline(debugger, IOHandler::Type::Expression,
564                             "lldb-expr", // Name of input reader for history
565                             llvm::StringRef(), // No prompt
566                             llvm::StringRef(), // Continuation prompt
567                             multiple_lines, color_prompt,
568                             1, // Show line numbers starting at 1
569                             *this));
570 
571   StreamFileSP output_sp(io_handler_sp->GetOutputStreamFile());
572   if (output_sp) {
573     output_sp->PutCString(
574         "Enter expressions, then terminate with an empty line to evaluate:\n");
575     output_sp->Flush();
576   }
577   debugger.PushIOHandler(io_handler_sp);
578 }
579 
580 bool CommandObjectExpression::DoExecute(llvm::StringRef command,
581                                         CommandReturnObject &result) {
582   m_fixed_expression.clear();
583   auto exe_ctx = GetCommandInterpreter().GetExecutionContext();
584   m_option_group.NotifyOptionParsingStarting(&exe_ctx);
585 
586   if (command.empty()) {
587     GetMultilineExpression();
588     return result.Succeeded();
589   }
590 
591   OptionsWithRaw args(command);
592   llvm::StringRef expr = args.GetRawPart();
593 
594   if (args.HasArgs()) {
595     if (!ParseOptionsAndNotify(args.GetArgs(), result, m_option_group, exe_ctx))
596       return false;
597 
598     if (m_repl_option.GetOptionValue().GetCurrentValue()) {
599       Target *target = m_interpreter.GetExecutionContext().GetTargetPtr();
600       if (target) {
601         // Drop into REPL
602         m_expr_lines.clear();
603         m_expr_line_count = 0;
604 
605         Debugger &debugger = target->GetDebugger();
606 
607         // Check if the LLDB command interpreter is sitting on top of a REPL
608         // that launched it...
609         if (debugger.CheckTopIOHandlerTypes(IOHandler::Type::CommandInterpreter,
610                                             IOHandler::Type::REPL)) {
611           // the LLDB command interpreter is sitting on top of a REPL that
612           // launched it, so just say the command interpreter is done and
613           // fall back to the existing REPL
614           m_interpreter.GetIOHandler(false)->SetIsDone(true);
615         } else {
616           // We are launching the REPL on top of the current LLDB command
617           // interpreter, so just push one
618           bool initialize = false;
619           Status repl_error;
620           REPLSP repl_sp(target->GetREPL(repl_error, m_command_options.language,
621                                          nullptr, false));
622 
623           if (!repl_sp) {
624             initialize = true;
625             repl_sp = target->GetREPL(repl_error, m_command_options.language,
626                                       nullptr, true);
627             if (!repl_error.Success()) {
628               result.SetError(repl_error);
629               return result.Succeeded();
630             }
631           }
632 
633           if (repl_sp) {
634             if (initialize) {
635               repl_sp->SetCommandOptions(m_command_options);
636               repl_sp->SetFormatOptions(m_format_options);
637               repl_sp->SetValueObjectDisplayOptions(m_varobj_options);
638             }
639 
640             IOHandlerSP io_handler_sp(repl_sp->GetIOHandler());
641 
642             io_handler_sp->SetIsDone(false);
643 
644             debugger.PushIOHandler(io_handler_sp);
645           } else {
646             repl_error.SetErrorStringWithFormat(
647                 "Couldn't create a REPL for %s",
648                 Language::GetNameForLanguageType(m_command_options.language));
649             result.SetError(repl_error);
650             return result.Succeeded();
651           }
652         }
653       }
654     }
655     // No expression following options
656     else if (expr.empty()) {
657       GetMultilineExpression();
658       return result.Succeeded();
659     }
660   }
661 
662   Target *target = GetSelectedOrDummyTarget();
663   if (EvaluateExpression(expr, &(result.GetOutputStream()),
664                          &(result.GetErrorStream()), &result)) {
665 
666     if (!m_fixed_expression.empty() && target->GetEnableNotifyAboutFixIts()) {
667       CommandHistory &history = m_interpreter.GetCommandHistory();
668       // FIXME: Can we figure out what the user actually typed (e.g. some alias
669       // for expr???)
670       // If we can it would be nice to show that.
671       std::string fixed_command("expression ");
672       if (args.HasArgs()) {
673         // Add in any options that might have been in the original command:
674         fixed_command.append(args.GetArgStringWithDelimiter());
675         fixed_command.append(m_fixed_expression);
676       } else
677         fixed_command.append(m_fixed_expression);
678       history.AppendString(fixed_command);
679     }
680     // Increment statistics to record this expression evaluation success.
681     target->IncrementStats(StatisticKind::ExpressionSuccessful);
682     return true;
683   }
684 
685   // Increment statistics to record this expression evaluation failure.
686   target->IncrementStats(StatisticKind::ExpressionFailure);
687   result.SetStatus(eReturnStatusFailed);
688   return false;
689 }
690