130fdc8d8SChris Lattner //===-- CommandObjectExpression.cpp -----------------------------*- C++ -*-===//
230fdc8d8SChris Lattner //
330fdc8d8SChris Lattner //                     The LLVM Compiler Infrastructure
430fdc8d8SChris Lattner //
530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source
630fdc8d8SChris Lattner // License. See LICENSE.TXT for details.
730fdc8d8SChris Lattner //
830fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
930fdc8d8SChris Lattner 
1030fdc8d8SChris Lattner #include "CommandObjectExpression.h"
1130fdc8d8SChris Lattner 
1230fdc8d8SChris Lattner // C Includes
1330fdc8d8SChris Lattner // C++ Includes
1430fdc8d8SChris Lattner // Other libraries and framework includes
1530fdc8d8SChris Lattner // Project includes
1630fdc8d8SChris Lattner #include "lldb/Core/Value.h"
176c68fb45SJim Ingham #include "lldb/Core/ValueObjectVariable.h"
184d93b8cdSEnrico Granata #include "lldb/DataFormatters/ValueObjectPrinter.h"
1930e33974SSean Callanan #include "Plugins/ExpressionParser/Clang/ClangExpressionVariable.h"
20151c032cSJim Ingham #include "lldb/Expression/UserExpression.h"
2130fdc8d8SChris Lattner #include "lldb/Expression/DWARFExpression.h"
22*f2bd5c3eSSean Callanan #include "lldb/Expression/REPL.h"
2330fdc8d8SChris Lattner #include "lldb/Host/Host.h"
245275aaa0SVince Harron #include "lldb/Host/StringConvert.h"
25ebf7707eSSean Callanan #include "lldb/Core/Debugger.h"
266611103cSGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h"
2730fdc8d8SChris Lattner #include "lldb/Interpreter/CommandReturnObject.h"
280e0984eeSJim Ingham #include "lldb/Target/Language.h"
2930fdc8d8SChris Lattner #include "lldb/Symbol/ObjectFile.h"
3030fdc8d8SChris Lattner #include "lldb/Symbol/Variable.h"
3130fdc8d8SChris Lattner #include "lldb/Target/Process.h"
32b57e4a1bSJason Molenda #include "lldb/Target/StackFrame.h"
3330fdc8d8SChris Lattner #include "lldb/Target/Target.h"
347260f620SGreg Clayton #include "lldb/Target/Thread.h"
3528606954SSaleem Abdulrasool #include "llvm/ADT/STLExtras.h"
36ebf7707eSSean Callanan #include "llvm/ADT/StringRef.h"
3730fdc8d8SChris Lattner 
3830fdc8d8SChris Lattner using namespace lldb;
3930fdc8d8SChris Lattner using namespace lldb_private;
4030fdc8d8SChris Lattner 
411deb7962SGreg Clayton CommandObjectExpression::CommandOptions::CommandOptions () :
421deb7962SGreg Clayton     OptionGroup()
4330fdc8d8SChris Lattner {
4430fdc8d8SChris Lattner }
4530fdc8d8SChris Lattner 
4630fdc8d8SChris Lattner 
4730fdc8d8SChris Lattner CommandObjectExpression::CommandOptions::~CommandOptions ()
4830fdc8d8SChris Lattner {
4930fdc8d8SChris Lattner }
5030fdc8d8SChris Lattner 
514d93b8cdSEnrico Granata static OptionEnumValueElement g_description_verbosity_type[] =
524d93b8cdSEnrico Granata {
534d93b8cdSEnrico Granata     { eLanguageRuntimeDescriptionDisplayVerbosityCompact,      "compact",       "Only show the description string"},
544d93b8cdSEnrico Granata     { eLanguageRuntimeDescriptionDisplayVerbosityFull,         "full",          "Show the full output, including persistent variable's name and type"},
554d93b8cdSEnrico Granata     { 0, NULL, NULL }
564d93b8cdSEnrico Granata };
574d93b8cdSEnrico Granata 
581deb7962SGreg Clayton OptionDefinition
591deb7962SGreg Clayton CommandObjectExpression::CommandOptions::g_option_table[] =
601deb7962SGreg Clayton {
61d37221dcSZachary Turner     { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "all-threads",        'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,    "Should we run all threads if the execution doesn't complete on one thread."},
62d37221dcSZachary Turner     { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "ignore-breakpoints", 'i', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,    "Ignore breakpoint hits while running expressions"},
63d37221dcSZachary Turner     { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "timeout",            't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeUnsignedInteger,  "Timeout value (in microseconds) for running the expression."},
64d37221dcSZachary Turner     { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "unwind-on-error",    'u', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,    "Clean up program state if the expression causes a crash, or raises a signal.  Note, unlike gdb hitting a breakpoint is controlled by another option (-i)."},
65d37221dcSZachary Turner     { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "debug",              'g', OptionParser::eNoArgument      , NULL, NULL, 0, eArgTypeNone,       "When specified, debug the JIT code by setting a breakpoint on the first instruction and forcing breakpoints to not be ignored (-i0) and no unwinding to happen on error (-u0)."},
6615663c53SDawn Perchik     { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "language",           'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage,   "Specifies the Language to use when parsing the expression.  If not set the target.language setting is used." },
67d37221dcSZachary Turner     { LLDB_OPT_SET_1, false, "description-verbosity", 'v', OptionParser::eOptionalArgument, NULL, g_description_verbosity_type, 0, eArgTypeDescriptionVerbosity,        "How verbose should the output of this expression be, if the object description is asked for."},
681deb7962SGreg Clayton };
691deb7962SGreg Clayton 
701deb7962SGreg Clayton 
711deb7962SGreg Clayton uint32_t
721deb7962SGreg Clayton CommandObjectExpression::CommandOptions::GetNumDefinitions ()
731deb7962SGreg Clayton {
7428606954SSaleem Abdulrasool     return llvm::array_lengthof(g_option_table);
751deb7962SGreg Clayton }
761deb7962SGreg Clayton 
7730fdc8d8SChris Lattner Error
781deb7962SGreg Clayton CommandObjectExpression::CommandOptions::SetOptionValue (CommandInterpreter &interpreter,
791deb7962SGreg Clayton                                                          uint32_t option_idx,
801deb7962SGreg Clayton                                                          const char *option_arg)
8130fdc8d8SChris Lattner {
8230fdc8d8SChris Lattner     Error error;
8330fdc8d8SChris Lattner 
843bcdfc0eSGreg Clayton     const int short_option = g_option_table[option_idx].short_option;
8530fdc8d8SChris Lattner 
8630fdc8d8SChris Lattner     switch (short_option)
8730fdc8d8SChris Lattner     {
8815663c53SDawn Perchik     case 'l':
890e0984eeSJim Ingham         language = Language::GetLanguageTypeFromString (option_arg);
9015663c53SDawn Perchik         if (language == eLanguageTypeUnknown)
9115663c53SDawn Perchik             error.SetErrorStringWithFormat ("unknown language type: '%s' for expression", option_arg);
9215663c53SDawn Perchik         break;
9330fdc8d8SChris Lattner 
9435e1bda6SJim Ingham     case 'a':
9535e1bda6SJim Ingham         {
9635e1bda6SJim Ingham             bool success;
9735e1bda6SJim Ingham             bool result;
9835e1bda6SJim Ingham             result = Args::StringToBoolean(option_arg, true, &success);
9935e1bda6SJim Ingham             if (!success)
10035e1bda6SJim Ingham                 error.SetErrorStringWithFormat("invalid all-threads value setting: \"%s\"", option_arg);
10135e1bda6SJim Ingham             else
10235e1bda6SJim Ingham                 try_all_threads = result;
10335e1bda6SJim Ingham         }
1046c68fb45SJim Ingham         break;
1056c68fb45SJim Ingham 
106184e9811SJim Ingham     case 'i':
107184e9811SJim Ingham         {
108184e9811SJim Ingham             bool success;
109184e9811SJim Ingham             bool tmp_value = Args::StringToBoolean(option_arg, true, &success);
110184e9811SJim Ingham             if (success)
111184e9811SJim Ingham                 ignore_breakpoints = tmp_value;
112184e9811SJim Ingham             else
113184e9811SJim Ingham                 error.SetErrorStringWithFormat("could not convert \"%s\" to a boolean value.", option_arg);
114184e9811SJim Ingham             break;
115184e9811SJim Ingham         }
11635e1bda6SJim Ingham     case 't':
11735e1bda6SJim Ingham         {
11835e1bda6SJim Ingham             bool success;
11935e1bda6SJim Ingham             uint32_t result;
1205275aaa0SVince Harron             result = StringConvert::ToUInt32(option_arg, 0, 0, &success);
12135e1bda6SJim Ingham             if (success)
12235e1bda6SJim Ingham                 timeout = result;
12335e1bda6SJim Ingham             else
12435e1bda6SJim Ingham                 error.SetErrorStringWithFormat ("invalid timeout setting \"%s\"", option_arg);
12535e1bda6SJim Ingham         }
12635e1bda6SJim Ingham         break;
12735e1bda6SJim Ingham 
128399f1cafSJim Ingham     case 'u':
1293bfdaa2aSSean Callanan         {
130399f1cafSJim Ingham             bool success;
131184e9811SJim Ingham             bool tmp_value = Args::StringToBoolean(option_arg, true, &success);
132184e9811SJim Ingham             if (success)
133184e9811SJim Ingham                 unwind_on_error = tmp_value;
134184e9811SJim Ingham             else
13586edbf41SGreg Clayton                 error.SetErrorStringWithFormat("could not convert \"%s\" to a boolean value.", option_arg);
136399f1cafSJim Ingham             break;
1373bfdaa2aSSean Callanan         }
1384d93b8cdSEnrico Granata 
1394d93b8cdSEnrico Granata     case 'v':
1404d93b8cdSEnrico Granata         if (!option_arg)
1414d93b8cdSEnrico Granata         {
1424d93b8cdSEnrico Granata             m_verbosity = eLanguageRuntimeDescriptionDisplayVerbosityFull;
1434d93b8cdSEnrico Granata             break;
1444d93b8cdSEnrico Granata         }
1454d93b8cdSEnrico Granata         m_verbosity = (LanguageRuntimeDescriptionDisplayVerbosity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error);
1464d93b8cdSEnrico Granata         if (!error.Success())
1474d93b8cdSEnrico Granata             error.SetErrorStringWithFormat ("unrecognized value for description-verbosity '%s'", option_arg);
1484d93b8cdSEnrico Granata         break;
1494d93b8cdSEnrico Granata 
15062afb9f6SGreg Clayton     case 'g':
15162afb9f6SGreg Clayton         debug = true;
15262afb9f6SGreg Clayton         unwind_on_error = false;
15362afb9f6SGreg Clayton         ignore_breakpoints = false;
15462afb9f6SGreg Clayton         break;
15562afb9f6SGreg Clayton 
15630fdc8d8SChris Lattner     default:
15786edbf41SGreg Clayton         error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
15830fdc8d8SChris Lattner         break;
15930fdc8d8SChris Lattner     }
16030fdc8d8SChris Lattner 
16130fdc8d8SChris Lattner     return error;
16230fdc8d8SChris Lattner }
16330fdc8d8SChris Lattner 
16430fdc8d8SChris Lattner void
1651deb7962SGreg Clayton CommandObjectExpression::CommandOptions::OptionParsingStarting (CommandInterpreter &interpreter)
16630fdc8d8SChris Lattner {
167184e9811SJim Ingham     Process *process = interpreter.GetExecutionContext().GetProcessPtr();
168184e9811SJim Ingham     if (process != NULL)
169184e9811SJim Ingham     {
170184e9811SJim Ingham         ignore_breakpoints = process->GetIgnoreBreakpointsInExpressions();
171184e9811SJim Ingham         unwind_on_error    = process->GetUnwindOnErrorInExpressions();
172184e9811SJim Ingham     }
173184e9811SJim Ingham     else
174184e9811SJim Ingham     {
175fc03f8fcSGreg Clayton         ignore_breakpoints = true;
176399f1cafSJim Ingham         unwind_on_error = true;
177184e9811SJim Ingham     }
178184e9811SJim Ingham 
17930fdc8d8SChris Lattner     show_summary = true;
18035e1bda6SJim Ingham     try_all_threads = true;
18135e1bda6SJim Ingham     timeout = 0;
18262afb9f6SGreg Clayton     debug = false;
18315663c53SDawn Perchik     language = eLanguageTypeUnknown;
1844d93b8cdSEnrico Granata     m_verbosity = eLanguageRuntimeDescriptionDisplayVerbosityCompact;
18530fdc8d8SChris Lattner }
18630fdc8d8SChris Lattner 
187e0d378b3SGreg Clayton const OptionDefinition*
18830fdc8d8SChris Lattner CommandObjectExpression::CommandOptions::GetDefinitions ()
18930fdc8d8SChris Lattner {
19030fdc8d8SChris Lattner     return g_option_table;
19130fdc8d8SChris Lattner }
19230fdc8d8SChris Lattner 
193a7015092SGreg Clayton CommandObjectExpression::CommandObjectExpression (CommandInterpreter &interpreter) :
1945a988416SJim Ingham     CommandObjectRaw (interpreter,
19530fdc8d8SChris Lattner                       "expression",
19615663c53SDawn Perchik                       "Evaluate an expression in the current program context, using user defined variables and variables currently in scope.",
1975a988416SJim Ingham                       NULL,
198e87764f2SEnrico Granata                       eCommandProcessMustBePaused | eCommandTryTargetAPILock),
19944d93782SGreg Clayton     IOHandlerDelegate (IOHandlerDelegate::Completion::Expression),
2001deb7962SGreg Clayton     m_option_group (interpreter),
2011deb7962SGreg Clayton     m_format_options (eFormatDefault),
202*f2bd5c3eSSean Callanan     m_repl_option (LLDB_OPT_SET_1, false, "repl", 'r', "Drop into REPL", false, true),
2031deb7962SGreg Clayton     m_command_options (),
20430fdc8d8SChris Lattner     m_expr_line_count (0),
20530fdc8d8SChris Lattner     m_expr_lines ()
20630fdc8d8SChris Lattner {
20730fdc8d8SChris Lattner     SetHelpLong(
208ea671fbdSKate Stone R"(
209ea671fbdSKate Stone Timeouts:
210ea671fbdSKate Stone 
211ea671fbdSKate Stone )" "    If the expression can be evaluated statically (without running code) then it will be.  \
212ea671fbdSKate Stone Otherwise, by default the expression will run on the current thread with a short timeout: \
213ea671fbdSKate Stone currently .25 seconds.  If it doesn't return in that time, the evaluation will be interrupted \
214ea671fbdSKate Stone and resumed with all threads running.  You can use the -a option to disable retrying on all \
215ea671fbdSKate Stone threads.  You can use the -t option to set a shorter timeout." R"(
216ea671fbdSKate Stone 
217ea671fbdSKate Stone User defined variables:
218ea671fbdSKate Stone 
219ea671fbdSKate Stone )" "    You can define your own variables for convenience or to be used in subsequent expressions.  \
220ea671fbdSKate Stone You define them the same way you would define variables in C.  If the first character of \
221ea671fbdSKate Stone your user defined variable is a $, then the variable's value will be available in future \
222ea671fbdSKate Stone expressions, otherwise it will just be available in the current expression." R"(
223ea671fbdSKate Stone 
224ea671fbdSKate Stone Continuing evaluation after a breakpoint:
225ea671fbdSKate Stone 
226ea671fbdSKate Stone )" "    If the \"-i false\" option is used, and execution is interrupted by a breakpoint hit, once \
227ea671fbdSKate Stone you are done with your investigation, you can either remove the expression execution frames \
228ea671fbdSKate Stone from the stack with \"thread return -x\" or if you are still interested in the expression result \
229ea671fbdSKate Stone you can issue the \"continue\" command and the expression evaluation will complete and the \
230ea671fbdSKate Stone expression result will be available using the \"thread.completed-expression\" key in the thread \
231ea671fbdSKate Stone format." R"(
232ea671fbdSKate Stone 
233ea671fbdSKate Stone Examples:
234ea671fbdSKate Stone 
235ea671fbdSKate Stone     expr my_struct->a = my_array[3]
236ea671fbdSKate Stone     expr -f bin -- (index * 8) + 5
237ea671fbdSKate Stone     expr unsigned int $foo = 5
238ea671fbdSKate Stone     expr char c[] = \"foo\"; c[0])"
239ea671fbdSKate Stone     );
240405fe67fSCaroline Tice 
241405fe67fSCaroline Tice     CommandArgumentEntry arg;
242405fe67fSCaroline Tice     CommandArgumentData expression_arg;
243405fe67fSCaroline Tice 
244405fe67fSCaroline Tice     // Define the first (and only) variant of this arg.
245405fe67fSCaroline Tice     expression_arg.arg_type = eArgTypeExpression;
246405fe67fSCaroline Tice     expression_arg.arg_repetition = eArgRepeatPlain;
247405fe67fSCaroline Tice 
248405fe67fSCaroline Tice     // There is only one variant this argument could be; put it into the argument entry.
249405fe67fSCaroline Tice     arg.push_back (expression_arg);
250405fe67fSCaroline Tice 
251405fe67fSCaroline Tice     // Push the data for the first argument into the m_arguments vector.
252405fe67fSCaroline Tice     m_arguments.push_back (arg);
2531deb7962SGreg Clayton 
2545009f9d5SGreg Clayton     // Add the "--format" and "--gdb-format"
2555009f9d5SGreg Clayton     m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_FORMAT | OptionGroupFormat::OPTION_GROUP_GDB_FMT, LLDB_OPT_SET_1);
2561deb7962SGreg Clayton     m_option_group.Append (&m_command_options);
257b576bba2SEnrico Granata     m_option_group.Append (&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1 | LLDB_OPT_SET_2);
258*f2bd5c3eSSean Callanan     m_option_group.Append (&m_repl_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_3);
2591deb7962SGreg Clayton     m_option_group.Finalize();
26030fdc8d8SChris Lattner }
26130fdc8d8SChris Lattner 
26230fdc8d8SChris Lattner CommandObjectExpression::~CommandObjectExpression ()
26330fdc8d8SChris Lattner {
26430fdc8d8SChris Lattner }
26530fdc8d8SChris Lattner 
26630fdc8d8SChris Lattner Options *
26730fdc8d8SChris Lattner CommandObjectExpression::GetOptions ()
26830fdc8d8SChris Lattner {
2691deb7962SGreg Clayton     return &m_option_group;
27030fdc8d8SChris Lattner }
27130fdc8d8SChris Lattner 
27230fdc8d8SChris Lattner bool
2731d3afba3SGreg Clayton CommandObjectExpression::EvaluateExpression
2741d3afba3SGreg Clayton (
2751d3afba3SGreg Clayton     const char *expr,
2766e8dc334SCaroline Tice     Stream *output_stream,
2776e8dc334SCaroline Tice     Stream *error_stream,
2781d3afba3SGreg Clayton     CommandReturnObject *result
2791d3afba3SGreg Clayton )
28030fdc8d8SChris Lattner {
281ba7b8e2cSGreg Clayton     // Don't use m_exe_ctx as this might be called asynchronously
282ba7b8e2cSGreg Clayton     // after the command object DoExecute has finished when doing
283ba7b8e2cSGreg Clayton     // multi-line expression that use an input reader...
284ba7b8e2cSGreg Clayton     ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
285ba7b8e2cSGreg Clayton 
286ba7b8e2cSGreg Clayton     Target *target = exe_ctx.GetTargetPtr();
287c0a6e061SSean Callanan 
288c0a6e061SSean Callanan     if (!target)
289893c932aSJim Ingham         target = GetDummyTarget();
290c0a6e061SSean Callanan 
291c14ee32dSGreg Clayton     if (target)
2926961e878SSean Callanan     {
2938b2fe6dcSGreg Clayton         lldb::ValueObjectSP result_valobj_sp;
29492adcac9SSean Callanan         bool keep_in_memory = true;
295009d110dSDawn Perchik         StackFrame *frame = exe_ctx.GetFramePtr();
29692adcac9SSean Callanan 
29735e1bda6SJim Ingham         EvaluateExpressionOptions options;
2986fbc48bcSJim Ingham         options.SetCoerceToId(m_varobj_options.use_objc);
2996fbc48bcSJim Ingham         options.SetUnwindOnError(m_command_options.unwind_on_error);
3006fbc48bcSJim Ingham         options.SetIgnoreBreakpoints (m_command_options.ignore_breakpoints);
3016fbc48bcSJim Ingham         options.SetKeepInMemory(keep_in_memory);
3026fbc48bcSJim Ingham         options.SetUseDynamic(m_varobj_options.use_dynamic);
3036fbc48bcSJim Ingham         options.SetTryAllThreads(m_command_options.try_all_threads);
3046fbc48bcSJim Ingham         options.SetDebug(m_command_options.debug);
30515663c53SDawn Perchik         options.SetLanguage(m_command_options.language);
30615663c53SDawn Perchik 
30723f8c95aSGreg Clayton         // If there is any chance we are going to stop and want to see
30823f8c95aSGreg Clayton         // what went wrong with our expression, we should generate debug info
30923f8c95aSGreg Clayton         if (!m_command_options.ignore_breakpoints ||
31023f8c95aSGreg Clayton             !m_command_options.unwind_on_error)
31123f8c95aSGreg Clayton             options.SetGenerateDebugInfo(true);
31223f8c95aSGreg Clayton 
31362afb9f6SGreg Clayton         if (m_command_options.timeout > 0)
31462afb9f6SGreg Clayton             options.SetTimeoutUsec(m_command_options.timeout);
3156f78f386SJim Ingham         else
3166f78f386SJim Ingham             options.SetTimeoutUsec(0);
317d4439aa9SEnrico Granata 
318009d110dSDawn Perchik         target->EvaluateExpression(expr, frame, result_valobj_sp, options);
3198b2fe6dcSGreg Clayton 
3208b2fe6dcSGreg Clayton         if (result_valobj_sp)
3218b2fe6dcSGreg Clayton         {
322bf154daeSSean Callanan             Format format = m_format_options.GetFormat();
323bf154daeSSean Callanan 
324b71f3844SGreg Clayton             if (result_valobj_sp->GetError().Success())
32530fdc8d8SChris Lattner             {
326bf154daeSSean Callanan                 if (format != eFormatVoid)
327bf154daeSSean Callanan                 {
3281deb7962SGreg Clayton                     if (format != eFormatDefault)
3291deb7962SGreg Clayton                         result_valobj_sp->SetFormat (format);
33032c4085bSGreg Clayton 
3314d93b8cdSEnrico Granata                     DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions(m_command_options.m_verbosity,format));
33273e8c4d0SEnrico Granata                     options.SetVariableFormatDisplayLanguage(result_valobj_sp->GetPreferredDisplayLanguage());
333770eb05aSEnrico Granata 
3344d93b8cdSEnrico Granata                     result_valobj_sp->Dump(*output_stream,options);
3354d93b8cdSEnrico Granata 
336fcd43b71SJohnny Chen                     if (result)
337fcd43b71SJohnny Chen                         result->SetStatus (eReturnStatusSuccessFinishResult);
33830fdc8d8SChris Lattner                 }
339bf154daeSSean Callanan             }
34030fdc8d8SChris Lattner             else
34130fdc8d8SChris Lattner             {
342151c032cSJim Ingham                 if (result_valobj_sp->GetError().GetError() == UserExpression::kNoResult)
343bccce813SSean Callanan                 {
344bcf897faSSean Callanan                     if (format != eFormatVoid && m_interpreter.GetDebugger().GetNotifyVoid())
345bf154daeSSean Callanan                     {
346bcf897faSSean Callanan                         error_stream->PutCString("(void)\n");
347bcf897faSSean Callanan                     }
348bccce813SSean Callanan 
349bccce813SSean Callanan                     if (result)
350bccce813SSean Callanan                         result->SetStatus (eReturnStatusSuccessFinishResult);
351bccce813SSean Callanan                 }
352bccce813SSean Callanan                 else
353bccce813SSean Callanan                 {
3545fd05903SGreg Clayton                     const char *error_cstr = result_valobj_sp->GetError().AsCString();
3555fd05903SGreg Clayton                     if (error_cstr && error_cstr[0])
3565fd05903SGreg Clayton                     {
357c7bece56SGreg Clayton                         const size_t error_cstr_len = strlen (error_cstr);
3585fd05903SGreg Clayton                         const bool ends_with_newline = error_cstr[error_cstr_len - 1] == '\n';
3595fd05903SGreg Clayton                         if (strstr(error_cstr, "error:") != error_cstr)
3605fd05903SGreg Clayton                             error_stream->PutCString ("error: ");
3615fd05903SGreg Clayton                         error_stream->Write(error_cstr, error_cstr_len);
3625fd05903SGreg Clayton                         if (!ends_with_newline)
3635fd05903SGreg Clayton                             error_stream->EOL();
3645fd05903SGreg Clayton                     }
3655fd05903SGreg Clayton                     else
3665fd05903SGreg Clayton                     {
3675fd05903SGreg Clayton                         error_stream->PutCString ("error: unknown error\n");
3685fd05903SGreg Clayton                     }
3695fd05903SGreg Clayton 
370fcd43b71SJohnny Chen                     if (result)
371b71f3844SGreg Clayton                         result->SetStatus (eReturnStatusFailed);
37230fdc8d8SChris Lattner                 }
3738b2fe6dcSGreg Clayton             }
3748b2fe6dcSGreg Clayton         }
375bccce813SSean Callanan     }
3768b2fe6dcSGreg Clayton     else
3778b2fe6dcSGreg Clayton     {
3786e8dc334SCaroline Tice         error_stream->Printf ("error: invalid execution context for expression\n");
3798b2fe6dcSGreg Clayton         return false;
3808b2fe6dcSGreg Clayton     }
38130fdc8d8SChris Lattner 
38216ad5faeSSean Callanan     return true;
38330fdc8d8SChris Lattner }
38430fdc8d8SChris Lattner 
38544d93782SGreg Clayton void
38644d93782SGreg Clayton CommandObjectExpression::IOHandlerInputComplete (IOHandler &io_handler, std::string &line)
38744d93782SGreg Clayton {
38844d93782SGreg Clayton     io_handler.SetIsDone(true);
38944d93782SGreg Clayton //    StreamSP output_stream = io_handler.GetDebugger().GetAsyncOutputStream();
39044d93782SGreg Clayton //    StreamSP error_stream = io_handler.GetDebugger().GetAsyncErrorStream();
39144d93782SGreg Clayton     StreamFileSP output_sp(io_handler.GetOutputStreamFile());
39244d93782SGreg Clayton     StreamFileSP error_sp(io_handler.GetErrorStreamFile());
39344d93782SGreg Clayton 
39444d93782SGreg Clayton     EvaluateExpression (line.c_str(),
39544d93782SGreg Clayton                         output_sp.get(),
39644d93782SGreg Clayton                         error_sp.get());
39744d93782SGreg Clayton     if (output_sp)
39844d93782SGreg Clayton         output_sp->Flush();
39944d93782SGreg Clayton     if (error_sp)
40044d93782SGreg Clayton         error_sp->Flush();
40144d93782SGreg Clayton }
40244d93782SGreg Clayton 
40344d93782SGreg Clayton LineStatus
40444d93782SGreg Clayton CommandObjectExpression::IOHandlerLinesUpdated (IOHandler &io_handler,
40544d93782SGreg Clayton                                                 StringList &lines,
40644d93782SGreg Clayton                                                 uint32_t line_idx,
40744d93782SGreg Clayton                                                 Error &error)
40844d93782SGreg Clayton {
40944d93782SGreg Clayton     if (line_idx == UINT32_MAX)
41044d93782SGreg Clayton     {
41144d93782SGreg Clayton         // Remove the last line from "lines" so it doesn't appear
41244d93782SGreg Clayton         // in our final expression
41344d93782SGreg Clayton         lines.PopBack();
41444d93782SGreg Clayton         error.Clear();
41544d93782SGreg Clayton         return LineStatus::Done;
41644d93782SGreg Clayton     }
41744d93782SGreg Clayton     else if (line_idx + 1 == lines.GetSize())
41844d93782SGreg Clayton     {
41944d93782SGreg Clayton         // The last line was edited, if this line is empty, then we are done
42044d93782SGreg Clayton         // getting our multiple lines.
42144d93782SGreg Clayton         if (lines[line_idx].empty())
42244d93782SGreg Clayton             return LineStatus::Done;
42344d93782SGreg Clayton     }
42444d93782SGreg Clayton     return LineStatus::Success;
42544d93782SGreg Clayton }
42644d93782SGreg Clayton 
427cf28a8b7SGreg Clayton void
428cf28a8b7SGreg Clayton CommandObjectExpression::GetMultilineExpression ()
42930fdc8d8SChris Lattner {
43030fdc8d8SChris Lattner     m_expr_lines.clear();
43130fdc8d8SChris Lattner     m_expr_line_count = 0;
43230fdc8d8SChris Lattner 
43344d93782SGreg Clayton     Debugger &debugger = GetCommandInterpreter().GetDebugger();
434e30f11d9SKate Stone     bool color_prompt = debugger.GetUseColor();
43544d93782SGreg Clayton     const bool multiple_lines = true; // Get multiple lines
43644d93782SGreg Clayton     IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger,
437e30f11d9SKate Stone                                                       IOHandler::Type::Expression,
43844d93782SGreg Clayton                                                       "lldb-expr",      // Name of input reader for history
43944d93782SGreg Clayton                                                       NULL,             // No prompt
440e30f11d9SKate Stone                                                       NULL,             // Continuation prompt
44144d93782SGreg Clayton                                                       multiple_lines,
442e30f11d9SKate Stone                                                       color_prompt,
443f6913cd7SGreg Clayton                                                       1,                // Show line numbers starting at 1
44444d93782SGreg Clayton                                                       *this));
445b6892508SGreg Clayton 
446b6892508SGreg Clayton     StreamFileSP output_sp(io_handler_sp->GetOutputStreamFile());
447b6892508SGreg Clayton     if (output_sp)
448b6892508SGreg Clayton     {
449b6892508SGreg Clayton         output_sp->PutCString("Enter expressions, then terminate with an empty line to evaluate:\n");
450b6892508SGreg Clayton         output_sp->Flush();
451b6892508SGreg Clayton     }
45244d93782SGreg Clayton     debugger.PushIOHandler(io_handler_sp);
453cf28a8b7SGreg Clayton }
454cf28a8b7SGreg Clayton 
455cf28a8b7SGreg Clayton bool
456cf28a8b7SGreg Clayton CommandObjectExpression::DoExecute
457cf28a8b7SGreg Clayton (
458cf28a8b7SGreg Clayton     const char *command,
459cf28a8b7SGreg Clayton     CommandReturnObject &result
460cf28a8b7SGreg Clayton )
461cf28a8b7SGreg Clayton {
462cf28a8b7SGreg Clayton     m_option_group.NotifyOptionParsingStarting();
463cf28a8b7SGreg Clayton 
464cf28a8b7SGreg Clayton     const char * expr = NULL;
465cf28a8b7SGreg Clayton 
466cf28a8b7SGreg Clayton     if (command[0] == '\0')
467cf28a8b7SGreg Clayton     {
468cf28a8b7SGreg Clayton         GetMultilineExpression ();
46930fdc8d8SChris Lattner         return result.Succeeded();
47030fdc8d8SChris Lattner     }
47130fdc8d8SChris Lattner 
47230fdc8d8SChris Lattner     if (command[0] == '-')
47330fdc8d8SChris Lattner     {
47430fdc8d8SChris Lattner         // We have some options and these options MUST end with --.
47530fdc8d8SChris Lattner         const char *end_options = NULL;
47630fdc8d8SChris Lattner         const char *s = command;
47730fdc8d8SChris Lattner         while (s && s[0])
47830fdc8d8SChris Lattner         {
47930fdc8d8SChris Lattner             end_options = ::strstr (s, "--");
48030fdc8d8SChris Lattner             if (end_options)
48130fdc8d8SChris Lattner             {
48230fdc8d8SChris Lattner                 end_options += 2; // Get past the "--"
48330fdc8d8SChris Lattner                 if (::isspace (end_options[0]))
48430fdc8d8SChris Lattner                 {
48530fdc8d8SChris Lattner                     expr = end_options;
48630fdc8d8SChris Lattner                     while (::isspace (*expr))
48730fdc8d8SChris Lattner                         ++expr;
48830fdc8d8SChris Lattner                     break;
48930fdc8d8SChris Lattner                 }
49030fdc8d8SChris Lattner             }
49130fdc8d8SChris Lattner             s = end_options;
49230fdc8d8SChris Lattner         }
49330fdc8d8SChris Lattner 
49430fdc8d8SChris Lattner         if (end_options)
49530fdc8d8SChris Lattner         {
49600b7f95bSPavel Labath             Args args (llvm::StringRef(command, end_options - command));
497a7015092SGreg Clayton             if (!ParseOptions (args, result))
49830fdc8d8SChris Lattner                 return false;
499f6b8b581SGreg Clayton 
5001deb7962SGreg Clayton             Error error (m_option_group.NotifyOptionParsingFinished());
501f6b8b581SGreg Clayton             if (error.Fail())
502f6b8b581SGreg Clayton             {
503f6b8b581SGreg Clayton                 result.AppendError (error.AsCString());
504f6b8b581SGreg Clayton                 result.SetStatus (eReturnStatusFailed);
505f6b8b581SGreg Clayton                 return false;
506f6b8b581SGreg Clayton             }
507cf28a8b7SGreg Clayton 
508*f2bd5c3eSSean Callanan             if (m_repl_option.GetOptionValue().GetCurrentValue())
509*f2bd5c3eSSean Callanan             {
510*f2bd5c3eSSean Callanan                 Target *target = m_interpreter.GetExecutionContext().GetTargetPtr();
511*f2bd5c3eSSean Callanan                 if (target)
512*f2bd5c3eSSean Callanan                 {
513*f2bd5c3eSSean Callanan                     // Drop into REPL
514*f2bd5c3eSSean Callanan                     m_expr_lines.clear();
515*f2bd5c3eSSean Callanan                     m_expr_line_count = 0;
516*f2bd5c3eSSean Callanan 
517*f2bd5c3eSSean Callanan                     Debugger &debugger = target->GetDebugger();
518*f2bd5c3eSSean Callanan 
519*f2bd5c3eSSean Callanan                     // Check if the LLDB command interpreter is sitting on top of a REPL that
520*f2bd5c3eSSean Callanan                     // launched it...
521*f2bd5c3eSSean Callanan                     if (debugger.CheckTopIOHandlerTypes(IOHandler::Type::CommandInterpreter, IOHandler::Type::REPL))
522*f2bd5c3eSSean Callanan                     {
523*f2bd5c3eSSean Callanan                         // the LLDB command interpreter is sitting on top of a REPL that launched it,
524*f2bd5c3eSSean Callanan                         // so just say the command interpreter is done and fall back to the existing REPL
525*f2bd5c3eSSean Callanan                         m_interpreter.GetIOHandler(false)->SetIsDone(true);
526*f2bd5c3eSSean Callanan                     }
527*f2bd5c3eSSean Callanan                     else
528*f2bd5c3eSSean Callanan                     {
529*f2bd5c3eSSean Callanan                         // We are launching the REPL on top of the current LLDB command interpreter,
530*f2bd5c3eSSean Callanan                         // so just push one
531*f2bd5c3eSSean Callanan                         bool initialize = false;
532*f2bd5c3eSSean Callanan                         Error repl_error;
533*f2bd5c3eSSean Callanan                         REPLSP repl_sp (target->GetREPL(repl_error, m_command_options.language, nullptr, false));
534*f2bd5c3eSSean Callanan 
535*f2bd5c3eSSean Callanan                         if (!repl_sp)
536*f2bd5c3eSSean Callanan                         {
537*f2bd5c3eSSean Callanan                             initialize = true;
538*f2bd5c3eSSean Callanan                             repl_sp = target->GetREPL(repl_error, m_command_options.language, nullptr, true);
539*f2bd5c3eSSean Callanan                             if (!repl_error.Success())
540*f2bd5c3eSSean Callanan                             {
541*f2bd5c3eSSean Callanan                                 result.SetError(repl_error);
542*f2bd5c3eSSean Callanan                                 return result.Succeeded();
543*f2bd5c3eSSean Callanan                             }
544*f2bd5c3eSSean Callanan                         }
545*f2bd5c3eSSean Callanan 
546*f2bd5c3eSSean Callanan                         if (repl_sp)
547*f2bd5c3eSSean Callanan                         {
548*f2bd5c3eSSean Callanan                             if (initialize)
549*f2bd5c3eSSean Callanan                             {
550*f2bd5c3eSSean Callanan                                 repl_sp->SetCommandOptions(m_command_options);
551*f2bd5c3eSSean Callanan                                 repl_sp->SetFormatOptions(m_format_options);
552*f2bd5c3eSSean Callanan                                 repl_sp->SetValueObjectDisplayOptions(m_varobj_options);
553*f2bd5c3eSSean Callanan                             }
554*f2bd5c3eSSean Callanan 
555*f2bd5c3eSSean Callanan                             IOHandlerSP io_handler_sp (repl_sp->GetIOHandler());
556*f2bd5c3eSSean Callanan 
557*f2bd5c3eSSean Callanan                             io_handler_sp->SetIsDone(false);
558*f2bd5c3eSSean Callanan 
559*f2bd5c3eSSean Callanan                             debugger.PushIOHandler(io_handler_sp);
560*f2bd5c3eSSean Callanan                         }
561*f2bd5c3eSSean Callanan                         else
562*f2bd5c3eSSean Callanan                         {
563*f2bd5c3eSSean Callanan                             repl_error.SetErrorStringWithFormat("Couldn't create a REPL for %s", Language::GetNameForLanguageType(m_command_options.language));
564*f2bd5c3eSSean Callanan                             result.SetError(repl_error);
565*f2bd5c3eSSean Callanan                             return result.Succeeded();
566*f2bd5c3eSSean Callanan                         }
567*f2bd5c3eSSean Callanan                     }
568*f2bd5c3eSSean Callanan                 }
569*f2bd5c3eSSean Callanan             }
570cf28a8b7SGreg Clayton             // No expression following options
571*f2bd5c3eSSean Callanan             else if (expr == NULL || expr[0] == '\0')
572cf28a8b7SGreg Clayton             {
573cf28a8b7SGreg Clayton                 GetMultilineExpression ();
574cf28a8b7SGreg Clayton                 return result.Succeeded();
575cf28a8b7SGreg Clayton             }
57630fdc8d8SChris Lattner         }
57730fdc8d8SChris Lattner     }
57830fdc8d8SChris Lattner 
57930fdc8d8SChris Lattner     if (expr == NULL)
58030fdc8d8SChris Lattner         expr = command;
58130fdc8d8SChris Lattner 
5826e8dc334SCaroline Tice     if (EvaluateExpression (expr, &(result.GetOutputStream()), &(result.GetErrorStream()), &result))
583fcd43b71SJohnny Chen         return true;
584fcd43b71SJohnny Chen 
585fcd43b71SJohnny Chen     result.SetStatus (eReturnStatusFailed);
586fcd43b71SJohnny Chen     return false;
58730fdc8d8SChris Lattner }
58830fdc8d8SChris Lattner 
589