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"
2230fdc8d8SChris Lattner #include "lldb/Host/Host.h"
235275aaa0SVince Harron #include "lldb/Host/StringConvert.h"
24ebf7707eSSean Callanan #include "lldb/Core/Debugger.h"
256611103cSGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h"
2630fdc8d8SChris Lattner #include "lldb/Interpreter/CommandReturnObject.h"
270e0984eeSJim Ingham #include "lldb/Target/Language.h"
2830fdc8d8SChris Lattner #include "lldb/Symbol/ObjectFile.h"
2930fdc8d8SChris Lattner #include "lldb/Symbol/Variable.h"
3030fdc8d8SChris Lattner #include "lldb/Target/Process.h"
31b57e4a1bSJason Molenda #include "lldb/Target/StackFrame.h"
3230fdc8d8SChris Lattner #include "lldb/Target/Target.h"
337260f620SGreg Clayton #include "lldb/Target/Thread.h"
3428606954SSaleem Abdulrasool #include "llvm/ADT/STLExtras.h"
35ebf7707eSSean Callanan #include "llvm/ADT/StringRef.h"
3630fdc8d8SChris Lattner 
3730fdc8d8SChris Lattner using namespace lldb;
3830fdc8d8SChris Lattner using namespace lldb_private;
3930fdc8d8SChris Lattner 
401deb7962SGreg Clayton CommandObjectExpression::CommandOptions::CommandOptions () :
411deb7962SGreg Clayton     OptionGroup()
4230fdc8d8SChris Lattner {
4330fdc8d8SChris Lattner }
4430fdc8d8SChris Lattner 
4530fdc8d8SChris Lattner 
4630fdc8d8SChris Lattner CommandObjectExpression::CommandOptions::~CommandOptions ()
4730fdc8d8SChris Lattner {
4830fdc8d8SChris Lattner }
4930fdc8d8SChris Lattner 
504d93b8cdSEnrico Granata static OptionEnumValueElement g_description_verbosity_type[] =
514d93b8cdSEnrico Granata {
524d93b8cdSEnrico Granata     { eLanguageRuntimeDescriptionDisplayVerbosityCompact,      "compact",       "Only show the description string"},
534d93b8cdSEnrico Granata     { eLanguageRuntimeDescriptionDisplayVerbosityFull,         "full",          "Show the full output, including persistent variable's name and type"},
544d93b8cdSEnrico Granata     { 0, NULL, NULL }
554d93b8cdSEnrico Granata };
564d93b8cdSEnrico Granata 
571deb7962SGreg Clayton OptionDefinition
581deb7962SGreg Clayton CommandObjectExpression::CommandOptions::g_option_table[] =
591deb7962SGreg Clayton {
60d37221dcSZachary 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."},
61d37221dcSZachary 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"},
62d37221dcSZachary 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."},
63d37221dcSZachary 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)."},
64d37221dcSZachary 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)."},
6515663c53SDawn 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." },
66d37221dcSZachary 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."},
671deb7962SGreg Clayton };
681deb7962SGreg Clayton 
691deb7962SGreg Clayton 
701deb7962SGreg Clayton uint32_t
711deb7962SGreg Clayton CommandObjectExpression::CommandOptions::GetNumDefinitions ()
721deb7962SGreg Clayton {
7328606954SSaleem Abdulrasool     return llvm::array_lengthof(g_option_table);
741deb7962SGreg Clayton }
751deb7962SGreg Clayton 
7630fdc8d8SChris Lattner Error
771deb7962SGreg Clayton CommandObjectExpression::CommandOptions::SetOptionValue (CommandInterpreter &interpreter,
781deb7962SGreg Clayton                                                          uint32_t option_idx,
791deb7962SGreg Clayton                                                          const char *option_arg)
8030fdc8d8SChris Lattner {
8130fdc8d8SChris Lattner     Error error;
8230fdc8d8SChris Lattner 
833bcdfc0eSGreg Clayton     const int short_option = g_option_table[option_idx].short_option;
8430fdc8d8SChris Lattner 
8530fdc8d8SChris Lattner     switch (short_option)
8630fdc8d8SChris Lattner     {
8715663c53SDawn Perchik     case 'l':
880e0984eeSJim Ingham         language = Language::GetLanguageTypeFromString (option_arg);
8915663c53SDawn Perchik         if (language == eLanguageTypeUnknown)
9015663c53SDawn Perchik             error.SetErrorStringWithFormat ("unknown language type: '%s' for expression", option_arg);
9115663c53SDawn Perchik         break;
9230fdc8d8SChris Lattner 
9335e1bda6SJim Ingham     case 'a':
9435e1bda6SJim Ingham         {
9535e1bda6SJim Ingham             bool success;
9635e1bda6SJim Ingham             bool result;
9735e1bda6SJim Ingham             result = Args::StringToBoolean(option_arg, true, &success);
9835e1bda6SJim Ingham             if (!success)
9935e1bda6SJim Ingham                 error.SetErrorStringWithFormat("invalid all-threads value setting: \"%s\"", option_arg);
10035e1bda6SJim Ingham             else
10135e1bda6SJim Ingham                 try_all_threads = result;
10235e1bda6SJim Ingham         }
1036c68fb45SJim Ingham         break;
1046c68fb45SJim Ingham 
105184e9811SJim Ingham     case 'i':
106184e9811SJim Ingham         {
107184e9811SJim Ingham             bool success;
108184e9811SJim Ingham             bool tmp_value = Args::StringToBoolean(option_arg, true, &success);
109184e9811SJim Ingham             if (success)
110184e9811SJim Ingham                 ignore_breakpoints = tmp_value;
111184e9811SJim Ingham             else
112184e9811SJim Ingham                 error.SetErrorStringWithFormat("could not convert \"%s\" to a boolean value.", option_arg);
113184e9811SJim Ingham             break;
114184e9811SJim Ingham         }
11535e1bda6SJim Ingham     case 't':
11635e1bda6SJim Ingham         {
11735e1bda6SJim Ingham             bool success;
11835e1bda6SJim Ingham             uint32_t result;
1195275aaa0SVince Harron             result = StringConvert::ToUInt32(option_arg, 0, 0, &success);
12035e1bda6SJim Ingham             if (success)
12135e1bda6SJim Ingham                 timeout = result;
12235e1bda6SJim Ingham             else
12335e1bda6SJim Ingham                 error.SetErrorStringWithFormat ("invalid timeout setting \"%s\"", option_arg);
12435e1bda6SJim Ingham         }
12535e1bda6SJim Ingham         break;
12635e1bda6SJim Ingham 
127399f1cafSJim Ingham     case 'u':
1283bfdaa2aSSean Callanan         {
129399f1cafSJim Ingham             bool success;
130184e9811SJim Ingham             bool tmp_value = Args::StringToBoolean(option_arg, true, &success);
131184e9811SJim Ingham             if (success)
132184e9811SJim Ingham                 unwind_on_error = tmp_value;
133184e9811SJim Ingham             else
13486edbf41SGreg Clayton                 error.SetErrorStringWithFormat("could not convert \"%s\" to a boolean value.", option_arg);
135399f1cafSJim Ingham             break;
1363bfdaa2aSSean Callanan         }
1374d93b8cdSEnrico Granata 
1384d93b8cdSEnrico Granata     case 'v':
1394d93b8cdSEnrico Granata         if (!option_arg)
1404d93b8cdSEnrico Granata         {
1414d93b8cdSEnrico Granata             m_verbosity = eLanguageRuntimeDescriptionDisplayVerbosityFull;
1424d93b8cdSEnrico Granata             break;
1434d93b8cdSEnrico Granata         }
1444d93b8cdSEnrico Granata         m_verbosity = (LanguageRuntimeDescriptionDisplayVerbosity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error);
1454d93b8cdSEnrico Granata         if (!error.Success())
1464d93b8cdSEnrico Granata             error.SetErrorStringWithFormat ("unrecognized value for description-verbosity '%s'", option_arg);
1474d93b8cdSEnrico Granata         break;
1484d93b8cdSEnrico Granata 
14962afb9f6SGreg Clayton     case 'g':
15062afb9f6SGreg Clayton         debug = true;
15162afb9f6SGreg Clayton         unwind_on_error = false;
15262afb9f6SGreg Clayton         ignore_breakpoints = false;
15362afb9f6SGreg Clayton         break;
15462afb9f6SGreg Clayton 
15530fdc8d8SChris Lattner     default:
15686edbf41SGreg Clayton         error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
15730fdc8d8SChris Lattner         break;
15830fdc8d8SChris Lattner     }
15930fdc8d8SChris Lattner 
16030fdc8d8SChris Lattner     return error;
16130fdc8d8SChris Lattner }
16230fdc8d8SChris Lattner 
16330fdc8d8SChris Lattner void
1641deb7962SGreg Clayton CommandObjectExpression::CommandOptions::OptionParsingStarting (CommandInterpreter &interpreter)
16530fdc8d8SChris Lattner {
166184e9811SJim Ingham     Process *process = interpreter.GetExecutionContext().GetProcessPtr();
167184e9811SJim Ingham     if (process != NULL)
168184e9811SJim Ingham     {
169184e9811SJim Ingham         ignore_breakpoints = process->GetIgnoreBreakpointsInExpressions();
170184e9811SJim Ingham         unwind_on_error    = process->GetUnwindOnErrorInExpressions();
171184e9811SJim Ingham     }
172184e9811SJim Ingham     else
173184e9811SJim Ingham     {
174fc03f8fcSGreg Clayton         ignore_breakpoints = true;
175399f1cafSJim Ingham         unwind_on_error = true;
176184e9811SJim Ingham     }
177184e9811SJim Ingham 
17830fdc8d8SChris Lattner     show_summary = true;
17935e1bda6SJim Ingham     try_all_threads = true;
18035e1bda6SJim Ingham     timeout = 0;
18162afb9f6SGreg Clayton     debug = false;
18215663c53SDawn Perchik     language = eLanguageTypeUnknown;
1834d93b8cdSEnrico Granata     m_verbosity = eLanguageRuntimeDescriptionDisplayVerbosityCompact;
18430fdc8d8SChris Lattner }
18530fdc8d8SChris Lattner 
186e0d378b3SGreg Clayton const OptionDefinition*
18730fdc8d8SChris Lattner CommandObjectExpression::CommandOptions::GetDefinitions ()
18830fdc8d8SChris Lattner {
18930fdc8d8SChris Lattner     return g_option_table;
19030fdc8d8SChris Lattner }
19130fdc8d8SChris Lattner 
192a7015092SGreg Clayton CommandObjectExpression::CommandObjectExpression (CommandInterpreter &interpreter) :
1935a988416SJim Ingham     CommandObjectRaw (interpreter,
19430fdc8d8SChris Lattner                       "expression",
19515663c53SDawn Perchik                       "Evaluate an expression in the current program context, using user defined variables and variables currently in scope.",
1965a988416SJim Ingham                       NULL,
197e87764f2SEnrico Granata                       eCommandProcessMustBePaused | eCommandTryTargetAPILock),
19844d93782SGreg Clayton     IOHandlerDelegate (IOHandlerDelegate::Completion::Expression),
1991deb7962SGreg Clayton     m_option_group (interpreter),
2001deb7962SGreg Clayton     m_format_options (eFormatDefault),
2011deb7962SGreg Clayton     m_command_options (),
20230fdc8d8SChris Lattner     m_expr_line_count (0),
20330fdc8d8SChris Lattner     m_expr_lines ()
20430fdc8d8SChris Lattner {
20530fdc8d8SChris Lattner     SetHelpLong(
206ea671fbdSKate Stone R"(
207ea671fbdSKate Stone Timeouts:
208ea671fbdSKate Stone 
209ea671fbdSKate Stone )" "    If the expression can be evaluated statically (without running code) then it will be.  \
210ea671fbdSKate Stone Otherwise, by default the expression will run on the current thread with a short timeout: \
211ea671fbdSKate Stone currently .25 seconds.  If it doesn't return in that time, the evaluation will be interrupted \
212ea671fbdSKate Stone and resumed with all threads running.  You can use the -a option to disable retrying on all \
213ea671fbdSKate Stone threads.  You can use the -t option to set a shorter timeout." R"(
214ea671fbdSKate Stone 
215ea671fbdSKate Stone User defined variables:
216ea671fbdSKate Stone 
217ea671fbdSKate Stone )" "    You can define your own variables for convenience or to be used in subsequent expressions.  \
218ea671fbdSKate Stone You define them the same way you would define variables in C.  If the first character of \
219ea671fbdSKate Stone your user defined variable is a $, then the variable's value will be available in future \
220ea671fbdSKate Stone expressions, otherwise it will just be available in the current expression." R"(
221ea671fbdSKate Stone 
222ea671fbdSKate Stone Continuing evaluation after a breakpoint:
223ea671fbdSKate Stone 
224ea671fbdSKate Stone )" "    If the \"-i false\" option is used, and execution is interrupted by a breakpoint hit, once \
225ea671fbdSKate Stone you are done with your investigation, you can either remove the expression execution frames \
226ea671fbdSKate Stone from the stack with \"thread return -x\" or if you are still interested in the expression result \
227ea671fbdSKate Stone you can issue the \"continue\" command and the expression evaluation will complete and the \
228ea671fbdSKate Stone expression result will be available using the \"thread.completed-expression\" key in the thread \
229ea671fbdSKate Stone format." R"(
230ea671fbdSKate Stone 
231ea671fbdSKate Stone Examples:
232ea671fbdSKate Stone 
233ea671fbdSKate Stone     expr my_struct->a = my_array[3]
234ea671fbdSKate Stone     expr -f bin -- (index * 8) + 5
235ea671fbdSKate Stone     expr unsigned int $foo = 5
236ea671fbdSKate Stone     expr char c[] = \"foo\"; c[0])"
237ea671fbdSKate Stone     );
238405fe67fSCaroline Tice 
239405fe67fSCaroline Tice     CommandArgumentEntry arg;
240405fe67fSCaroline Tice     CommandArgumentData expression_arg;
241405fe67fSCaroline Tice 
242405fe67fSCaroline Tice     // Define the first (and only) variant of this arg.
243405fe67fSCaroline Tice     expression_arg.arg_type = eArgTypeExpression;
244405fe67fSCaroline Tice     expression_arg.arg_repetition = eArgRepeatPlain;
245405fe67fSCaroline Tice 
246405fe67fSCaroline Tice     // There is only one variant this argument could be; put it into the argument entry.
247405fe67fSCaroline Tice     arg.push_back (expression_arg);
248405fe67fSCaroline Tice 
249405fe67fSCaroline Tice     // Push the data for the first argument into the m_arguments vector.
250405fe67fSCaroline Tice     m_arguments.push_back (arg);
2511deb7962SGreg Clayton 
2525009f9d5SGreg Clayton     // Add the "--format" and "--gdb-format"
2535009f9d5SGreg Clayton     m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_FORMAT | OptionGroupFormat::OPTION_GROUP_GDB_FMT, LLDB_OPT_SET_1);
2541deb7962SGreg Clayton     m_option_group.Append (&m_command_options);
255b576bba2SEnrico Granata     m_option_group.Append (&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1 | LLDB_OPT_SET_2);
2561deb7962SGreg Clayton     m_option_group.Finalize();
25730fdc8d8SChris Lattner }
25830fdc8d8SChris Lattner 
25930fdc8d8SChris Lattner CommandObjectExpression::~CommandObjectExpression ()
26030fdc8d8SChris Lattner {
26130fdc8d8SChris Lattner }
26230fdc8d8SChris Lattner 
26330fdc8d8SChris Lattner Options *
26430fdc8d8SChris Lattner CommandObjectExpression::GetOptions ()
26530fdc8d8SChris Lattner {
2661deb7962SGreg Clayton     return &m_option_group;
26730fdc8d8SChris Lattner }
26830fdc8d8SChris Lattner 
26930fdc8d8SChris Lattner bool
2701d3afba3SGreg Clayton CommandObjectExpression::EvaluateExpression
2711d3afba3SGreg Clayton (
2721d3afba3SGreg Clayton     const char *expr,
2736e8dc334SCaroline Tice     Stream *output_stream,
2746e8dc334SCaroline Tice     Stream *error_stream,
2751d3afba3SGreg Clayton     CommandReturnObject *result
2761d3afba3SGreg Clayton )
27730fdc8d8SChris Lattner {
278ba7b8e2cSGreg Clayton     // Don't use m_exe_ctx as this might be called asynchronously
279ba7b8e2cSGreg Clayton     // after the command object DoExecute has finished when doing
280ba7b8e2cSGreg Clayton     // multi-line expression that use an input reader...
281ba7b8e2cSGreg Clayton     ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
282ba7b8e2cSGreg Clayton 
283ba7b8e2cSGreg Clayton     Target *target = exe_ctx.GetTargetPtr();
284c0a6e061SSean Callanan 
285c0a6e061SSean Callanan     if (!target)
286893c932aSJim Ingham         target = GetDummyTarget();
287c0a6e061SSean Callanan 
288c14ee32dSGreg Clayton     if (target)
2896961e878SSean Callanan     {
2908b2fe6dcSGreg Clayton         lldb::ValueObjectSP result_valobj_sp;
29192adcac9SSean Callanan         bool keep_in_memory = true;
292009d110dSDawn Perchik         StackFrame *frame = exe_ctx.GetFramePtr();
29392adcac9SSean Callanan 
29435e1bda6SJim Ingham         EvaluateExpressionOptions options;
2956fbc48bcSJim Ingham         options.SetCoerceToId(m_varobj_options.use_objc);
2966fbc48bcSJim Ingham         options.SetUnwindOnError(m_command_options.unwind_on_error);
2976fbc48bcSJim Ingham         options.SetIgnoreBreakpoints (m_command_options.ignore_breakpoints);
2986fbc48bcSJim Ingham         options.SetKeepInMemory(keep_in_memory);
2996fbc48bcSJim Ingham         options.SetUseDynamic(m_varobj_options.use_dynamic);
3006fbc48bcSJim Ingham         options.SetTryAllThreads(m_command_options.try_all_threads);
3016fbc48bcSJim Ingham         options.SetDebug(m_command_options.debug);
30262afb9f6SGreg Clayton 
303009d110dSDawn Perchik         // If the language was not specified in the expression command,
304009d110dSDawn Perchik         // set it to the language in the target's properties if
305009d110dSDawn Perchik         // specified, else default to the langage for the frame.
30615663c53SDawn Perchik         if (m_command_options.language != eLanguageTypeUnknown)
30715663c53SDawn Perchik             options.SetLanguage(m_command_options.language);
308009d110dSDawn Perchik         else if (target->GetLanguage() != eLanguageTypeUnknown)
30915663c53SDawn Perchik             options.SetLanguage(target->GetLanguage());
310009d110dSDawn Perchik         else if (frame)
311009d110dSDawn Perchik             options.SetLanguage(frame->GetLanguage());
31215663c53SDawn Perchik 
31323f8c95aSGreg Clayton         // If there is any chance we are going to stop and want to see
31423f8c95aSGreg Clayton         // what went wrong with our expression, we should generate debug info
31523f8c95aSGreg Clayton         if (!m_command_options.ignore_breakpoints ||
31623f8c95aSGreg Clayton             !m_command_options.unwind_on_error)
31723f8c95aSGreg Clayton             options.SetGenerateDebugInfo(true);
31823f8c95aSGreg Clayton 
31962afb9f6SGreg Clayton         if (m_command_options.timeout > 0)
32062afb9f6SGreg Clayton             options.SetTimeoutUsec(m_command_options.timeout);
3216f78f386SJim Ingham         else
3226f78f386SJim Ingham             options.SetTimeoutUsec(0);
323d4439aa9SEnrico Granata 
324009d110dSDawn Perchik         target->EvaluateExpression(expr, frame, result_valobj_sp, options);
3258b2fe6dcSGreg Clayton 
3268b2fe6dcSGreg Clayton         if (result_valobj_sp)
3278b2fe6dcSGreg Clayton         {
328bf154daeSSean Callanan             Format format = m_format_options.GetFormat();
329bf154daeSSean Callanan 
330b71f3844SGreg Clayton             if (result_valobj_sp->GetError().Success())
33130fdc8d8SChris Lattner             {
332bf154daeSSean Callanan                 if (format != eFormatVoid)
333bf154daeSSean Callanan                 {
3341deb7962SGreg Clayton                     if (format != eFormatDefault)
3351deb7962SGreg Clayton                         result_valobj_sp->SetFormat (format);
33632c4085bSGreg Clayton 
3374d93b8cdSEnrico Granata                     DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions(m_command_options.m_verbosity,format));
338*73e8c4d0SEnrico Granata                     options.SetVariableFormatDisplayLanguage(result_valobj_sp->GetPreferredDisplayLanguage());
339770eb05aSEnrico Granata 
3404d93b8cdSEnrico Granata                     result_valobj_sp->Dump(*output_stream,options);
3414d93b8cdSEnrico Granata 
342fcd43b71SJohnny Chen                     if (result)
343fcd43b71SJohnny Chen                         result->SetStatus (eReturnStatusSuccessFinishResult);
34430fdc8d8SChris Lattner                 }
345bf154daeSSean Callanan             }
34630fdc8d8SChris Lattner             else
34730fdc8d8SChris Lattner             {
348151c032cSJim Ingham                 if (result_valobj_sp->GetError().GetError() == UserExpression::kNoResult)
349bccce813SSean Callanan                 {
350bcf897faSSean Callanan                     if (format != eFormatVoid && m_interpreter.GetDebugger().GetNotifyVoid())
351bf154daeSSean Callanan                     {
352bcf897faSSean Callanan                         error_stream->PutCString("(void)\n");
353bcf897faSSean Callanan                     }
354bccce813SSean Callanan 
355bccce813SSean Callanan                     if (result)
356bccce813SSean Callanan                         result->SetStatus (eReturnStatusSuccessFinishResult);
357bccce813SSean Callanan                 }
358bccce813SSean Callanan                 else
359bccce813SSean Callanan                 {
3605fd05903SGreg Clayton                     const char *error_cstr = result_valobj_sp->GetError().AsCString();
3615fd05903SGreg Clayton                     if (error_cstr && error_cstr[0])
3625fd05903SGreg Clayton                     {
363c7bece56SGreg Clayton                         const size_t error_cstr_len = strlen (error_cstr);
3645fd05903SGreg Clayton                         const bool ends_with_newline = error_cstr[error_cstr_len - 1] == '\n';
3655fd05903SGreg Clayton                         if (strstr(error_cstr, "error:") != error_cstr)
3665fd05903SGreg Clayton                             error_stream->PutCString ("error: ");
3675fd05903SGreg Clayton                         error_stream->Write(error_cstr, error_cstr_len);
3685fd05903SGreg Clayton                         if (!ends_with_newline)
3695fd05903SGreg Clayton                             error_stream->EOL();
3705fd05903SGreg Clayton                     }
3715fd05903SGreg Clayton                     else
3725fd05903SGreg Clayton                     {
3735fd05903SGreg Clayton                         error_stream->PutCString ("error: unknown error\n");
3745fd05903SGreg Clayton                     }
3755fd05903SGreg Clayton 
376fcd43b71SJohnny Chen                     if (result)
377b71f3844SGreg Clayton                         result->SetStatus (eReturnStatusFailed);
37830fdc8d8SChris Lattner                 }
3798b2fe6dcSGreg Clayton             }
3808b2fe6dcSGreg Clayton         }
381bccce813SSean Callanan     }
3828b2fe6dcSGreg Clayton     else
3838b2fe6dcSGreg Clayton     {
3846e8dc334SCaroline Tice         error_stream->Printf ("error: invalid execution context for expression\n");
3858b2fe6dcSGreg Clayton         return false;
3868b2fe6dcSGreg Clayton     }
38730fdc8d8SChris Lattner 
38816ad5faeSSean Callanan     return true;
38930fdc8d8SChris Lattner }
39030fdc8d8SChris Lattner 
39144d93782SGreg Clayton void
39244d93782SGreg Clayton CommandObjectExpression::IOHandlerInputComplete (IOHandler &io_handler, std::string &line)
39344d93782SGreg Clayton {
39444d93782SGreg Clayton     io_handler.SetIsDone(true);
39544d93782SGreg Clayton //    StreamSP output_stream = io_handler.GetDebugger().GetAsyncOutputStream();
39644d93782SGreg Clayton //    StreamSP error_stream = io_handler.GetDebugger().GetAsyncErrorStream();
39744d93782SGreg Clayton     StreamFileSP output_sp(io_handler.GetOutputStreamFile());
39844d93782SGreg Clayton     StreamFileSP error_sp(io_handler.GetErrorStreamFile());
39944d93782SGreg Clayton 
40044d93782SGreg Clayton     EvaluateExpression (line.c_str(),
40144d93782SGreg Clayton                         output_sp.get(),
40244d93782SGreg Clayton                         error_sp.get());
40344d93782SGreg Clayton     if (output_sp)
40444d93782SGreg Clayton         output_sp->Flush();
40544d93782SGreg Clayton     if (error_sp)
40644d93782SGreg Clayton         error_sp->Flush();
40744d93782SGreg Clayton }
40844d93782SGreg Clayton 
40944d93782SGreg Clayton LineStatus
41044d93782SGreg Clayton CommandObjectExpression::IOHandlerLinesUpdated (IOHandler &io_handler,
41144d93782SGreg Clayton                                                 StringList &lines,
41244d93782SGreg Clayton                                                 uint32_t line_idx,
41344d93782SGreg Clayton                                                 Error &error)
41444d93782SGreg Clayton {
41544d93782SGreg Clayton     if (line_idx == UINT32_MAX)
41644d93782SGreg Clayton     {
41744d93782SGreg Clayton         // Remove the last line from "lines" so it doesn't appear
41844d93782SGreg Clayton         // in our final expression
41944d93782SGreg Clayton         lines.PopBack();
42044d93782SGreg Clayton         error.Clear();
42144d93782SGreg Clayton         return LineStatus::Done;
42244d93782SGreg Clayton     }
42344d93782SGreg Clayton     else if (line_idx + 1 == lines.GetSize())
42444d93782SGreg Clayton     {
42544d93782SGreg Clayton         // The last line was edited, if this line is empty, then we are done
42644d93782SGreg Clayton         // getting our multiple lines.
42744d93782SGreg Clayton         if (lines[line_idx].empty())
42844d93782SGreg Clayton             return LineStatus::Done;
42944d93782SGreg Clayton     }
43044d93782SGreg Clayton     return LineStatus::Success;
43144d93782SGreg Clayton }
43244d93782SGreg Clayton 
433cf28a8b7SGreg Clayton void
434cf28a8b7SGreg Clayton CommandObjectExpression::GetMultilineExpression ()
43530fdc8d8SChris Lattner {
43630fdc8d8SChris Lattner     m_expr_lines.clear();
43730fdc8d8SChris Lattner     m_expr_line_count = 0;
43830fdc8d8SChris Lattner 
43944d93782SGreg Clayton     Debugger &debugger = GetCommandInterpreter().GetDebugger();
440e30f11d9SKate Stone     bool color_prompt = debugger.GetUseColor();
44144d93782SGreg Clayton     const bool multiple_lines = true; // Get multiple lines
44244d93782SGreg Clayton     IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger,
443e30f11d9SKate Stone                                                       IOHandler::Type::Expression,
44444d93782SGreg Clayton                                                       "lldb-expr",      // Name of input reader for history
44544d93782SGreg Clayton                                                       NULL,             // No prompt
446e30f11d9SKate Stone                                                       NULL,             // Continuation prompt
44744d93782SGreg Clayton                                                       multiple_lines,
448e30f11d9SKate Stone                                                       color_prompt,
449f6913cd7SGreg Clayton                                                       1,                // Show line numbers starting at 1
45044d93782SGreg Clayton                                                       *this));
451b6892508SGreg Clayton 
452b6892508SGreg Clayton     StreamFileSP output_sp(io_handler_sp->GetOutputStreamFile());
453b6892508SGreg Clayton     if (output_sp)
454b6892508SGreg Clayton     {
455b6892508SGreg Clayton         output_sp->PutCString("Enter expressions, then terminate with an empty line to evaluate:\n");
456b6892508SGreg Clayton         output_sp->Flush();
457b6892508SGreg Clayton     }
45844d93782SGreg Clayton     debugger.PushIOHandler(io_handler_sp);
459cf28a8b7SGreg Clayton }
460cf28a8b7SGreg Clayton 
461cf28a8b7SGreg Clayton bool
462cf28a8b7SGreg Clayton CommandObjectExpression::DoExecute
463cf28a8b7SGreg Clayton (
464cf28a8b7SGreg Clayton     const char *command,
465cf28a8b7SGreg Clayton     CommandReturnObject &result
466cf28a8b7SGreg Clayton )
467cf28a8b7SGreg Clayton {
468cf28a8b7SGreg Clayton     m_option_group.NotifyOptionParsingStarting();
469cf28a8b7SGreg Clayton 
470cf28a8b7SGreg Clayton     const char * expr = NULL;
471cf28a8b7SGreg Clayton 
472cf28a8b7SGreg Clayton     if (command[0] == '\0')
473cf28a8b7SGreg Clayton     {
474cf28a8b7SGreg Clayton         GetMultilineExpression ();
47530fdc8d8SChris Lattner         return result.Succeeded();
47630fdc8d8SChris Lattner     }
47730fdc8d8SChris Lattner 
47830fdc8d8SChris Lattner     if (command[0] == '-')
47930fdc8d8SChris Lattner     {
48030fdc8d8SChris Lattner         // We have some options and these options MUST end with --.
48130fdc8d8SChris Lattner         const char *end_options = NULL;
48230fdc8d8SChris Lattner         const char *s = command;
48330fdc8d8SChris Lattner         while (s && s[0])
48430fdc8d8SChris Lattner         {
48530fdc8d8SChris Lattner             end_options = ::strstr (s, "--");
48630fdc8d8SChris Lattner             if (end_options)
48730fdc8d8SChris Lattner             {
48830fdc8d8SChris Lattner                 end_options += 2; // Get past the "--"
48930fdc8d8SChris Lattner                 if (::isspace (end_options[0]))
49030fdc8d8SChris Lattner                 {
49130fdc8d8SChris Lattner                     expr = end_options;
49230fdc8d8SChris Lattner                     while (::isspace (*expr))
49330fdc8d8SChris Lattner                         ++expr;
49430fdc8d8SChris Lattner                     break;
49530fdc8d8SChris Lattner                 }
49630fdc8d8SChris Lattner             }
49730fdc8d8SChris Lattner             s = end_options;
49830fdc8d8SChris Lattner         }
49930fdc8d8SChris Lattner 
50030fdc8d8SChris Lattner         if (end_options)
50130fdc8d8SChris Lattner         {
50200b7f95bSPavel Labath             Args args (llvm::StringRef(command, end_options - command));
503a7015092SGreg Clayton             if (!ParseOptions (args, result))
50430fdc8d8SChris Lattner                 return false;
505f6b8b581SGreg Clayton 
5061deb7962SGreg Clayton             Error error (m_option_group.NotifyOptionParsingFinished());
507f6b8b581SGreg Clayton             if (error.Fail())
508f6b8b581SGreg Clayton             {
509f6b8b581SGreg Clayton                 result.AppendError (error.AsCString());
510f6b8b581SGreg Clayton                 result.SetStatus (eReturnStatusFailed);
511f6b8b581SGreg Clayton                 return false;
512f6b8b581SGreg Clayton             }
513cf28a8b7SGreg Clayton 
514cf28a8b7SGreg Clayton             // No expression following options
51505da458cSGreg Clayton             if (expr == NULL || expr[0] == '\0')
516cf28a8b7SGreg Clayton             {
517cf28a8b7SGreg Clayton                 GetMultilineExpression ();
518cf28a8b7SGreg Clayton                 return result.Succeeded();
519cf28a8b7SGreg Clayton             }
52030fdc8d8SChris Lattner         }
52130fdc8d8SChris Lattner     }
52230fdc8d8SChris Lattner 
52330fdc8d8SChris Lattner     if (expr == NULL)
52430fdc8d8SChris Lattner         expr = command;
52530fdc8d8SChris Lattner 
5266e8dc334SCaroline Tice     if (EvaluateExpression (expr, &(result.GetOutputStream()), &(result.GetErrorStream()), &result))
527fcd43b71SJohnny Chen         return true;
528fcd43b71SJohnny Chen 
529fcd43b71SJohnny Chen     result.SetStatus (eReturnStatusFailed);
530fcd43b71SJohnny Chen     return false;
53130fdc8d8SChris Lattner }
53230fdc8d8SChris Lattner 
533