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