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